├── .clang-format.todo ├── .clang-tidy ├── .github └── workflows │ ├── cmake.yml │ └── release.yml ├── .gitignore ├── CMake ├── Modules │ └── FindGMP.cmake └── bncsutilConfig.cmake.in ├── CMakeLists.txt ├── COPYING ├── README.md ├── conanfile.py ├── src └── bncsutil │ ├── bncsutil.h │ ├── bsha1.cpp │ ├── bsha1.h │ ├── buffer.h │ ├── cdkeydecoder.cpp │ ├── cdkeydecoder.h │ ├── checkrevision.cpp │ ├── checkrevision.h │ ├── decodekey.cpp │ ├── decodekey.h │ ├── file.cpp │ ├── file.h │ ├── keytables.h │ ├── libinfo.cpp │ ├── libinfo.h │ ├── ms_stdint.h │ ├── mutil.h │ ├── mutil_types.h │ ├── nls.c │ ├── nls.h │ ├── oldauth.cpp │ ├── oldauth.h │ ├── pe.c │ ├── pe.h │ ├── sha1.c │ ├── sha1.h │ ├── stack.c │ └── stack.h └── vb6_example ├── .gitattributes ├── BNCSutil.bas ├── BNCSutilExample.exe ├── BNCSutilExample.vbp ├── BNCSutilExample.vbw ├── Connection.bas ├── Interface.bas ├── MSSCCPRJ.SCC ├── NLS.cls ├── Packet.cls ├── frmMain.frm ├── frmNewAccount.frm └── frmNewAccount.frx /.clang-format.todo: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | BasedOnStyle: llvm 3 | Standard: c++11 4 | TabWidth: 4 5 | PointerAlignment: Right 6 | NamespaceIndentation: None -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: ' 2 | bugprone-* 3 | ,cert-* 4 | ,cppcoreguidelines-* 5 | ,modernize-* 6 | ,performance-* 7 | ,readability-* 8 | ,portability-* 9 | ,clang-analyzer-unix 10 | ,clang-analyzer-security 11 | ,clang-analyzer-deadcode 12 | ,clang-analyzer-core 13 | ,clang-analyzer-cplusplus 14 | ,clang-analyzer-optin 15 | ,llvm-namespace-comment 16 | ,readability-static-accessed-through-instance 17 | ,misc-const-correctness 18 | ,-bugprone-reserved-identifier 19 | ,-bugprone-implicit-widening-of-multiplication-result 20 | ,-bugprone-easily-swappable-parameters 21 | ,-bugprone-narrowing-conversions 22 | ,-cert-dcl37-c 23 | ,-cert-dcl51-cpp 24 | ,-cert-msc32-c 25 | ,-cert-msc51-cpp 26 | ,-cert-msc30-c 27 | ,-cert-msc50-cpp 28 | ,-modernize-use-trailing-return-type 29 | ,-modernize-macro-to-enum 30 | ,-modernize-use-nullptr 31 | ,-modernize-use-using 32 | ,-modernize-avoid-c-arrays 33 | ,-modernize-use-auto 34 | ,-readability-avoid-unconditional-preprocessor-if 35 | ,-readability-identifier-length 36 | ,-readability-isolate-declaration 37 | ,-readability-magic-numbers 38 | ,-readability-braces-around-statements 39 | ,-readability-function-cognitive-complexity 40 | ,-cppcoreguidelines-macro-to-enum 41 | ,-cppcoreguidelines-macro-usage 42 | ,-cppcoreguidelines-pro-bounds-pointer-arithmetic 43 | ,-cppcoreguidelines-pro-type-cstyle-cast 44 | ,-cppcoreguidelines-init-variables 45 | ,-cppcoreguidelines-avoid-magic-numbers 46 | ,-cppcoreguidelines-pro-bounds-array-to-pointer-decay 47 | ,-cppcoreguidelines-avoid-c-arrays 48 | ,-cppcoreguidelines-narrowing-conversions 49 | ' -------------------------------------------------------------------------------- /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | name: CMake 2 | 3 | on: [push, pull_request] 4 | 5 | env: 6 | BUILD_TYPE: Release 7 | 8 | jobs: 9 | build-debian-system-reproducible: 10 | if: true 11 | runs-on: ubuntu-latest 12 | container: 13 | image: debian:bookworm 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: Install dependencies 19 | run: apt-get -y update && apt-get install -y libgmp-dev build-essential cmake 20 | 21 | - name: Cmake pass 1 22 | run: cmake -G "Unix Makefiles" -B./build1 -DCMAKE_BUILD_TYPE=$BUILD_TYPE 23 | 24 | - name: Build pass 1 25 | run: cmake --build ./build1 26 | 27 | - name: Cmake pass 2 28 | run: cmake -G "Unix Makefiles" -B./build2 -DCMAKE_BUILD_TYPE=$BUILD_TYPE 29 | 30 | - name: Build pass 2 31 | run: cmake --build ./build2 32 | 33 | - name: Check hashes 34 | run: | 35 | ls -la build1 36 | hash1=$(sha256sum build1/libbncsutil.so | cut -d ' ' -f 1) 37 | hash2=$(sha256sum build2/libbncsutil.so | cut -d ' ' -f 1) 38 | echo "Hash 1: $hash1\n" 39 | echo "Hash 2: $hash2\n" 40 | [ "$hash1" = "$hash2" ] && exit 0 || exit 1 41 | 42 | build-debian-conan: 43 | if: true 44 | runs-on: ubuntu-latest 45 | container: 46 | image: debian:bookworm 47 | 48 | steps: 49 | - uses: actions/checkout@v4 50 | 51 | - name: Install dependencies 52 | run: apt-get -y update && apt-get install -y python3 python3-pip build-essential cmake 53 | 54 | - name: Install conan 55 | run: pip install conan --break-system-packages 56 | 57 | - name: Init conan 58 | run: conan profile detect 59 | 60 | - name: Install deps with conan 61 | run: conan install . -of build -s build_type=$BUILD_TYPE --build=missing 62 | 63 | - name: Cmake 64 | working-directory: build 65 | run: bash conanbuild.sh && cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DUSE_SYSTEM_LIBS=0 66 | 67 | - name: Build 68 | working-directory: build 69 | run: cmake --build . --config Release 70 | 71 | build-fedora-system: 72 | if: true 73 | runs-on: ubuntu-latest 74 | container: 75 | image: fedora:latest 76 | 77 | steps: 78 | - uses: actions/checkout@v4 79 | 80 | - name: Install dependencies 81 | run: dnf -y install gmp-devel make automake clang cmake 82 | 83 | - name: Cmake 84 | run: cmake -G "Unix Makefiles" -B./build -DCMAKE_BUILD_TYPE=$BUILD_TYPE 85 | 86 | - name: Build 87 | run: cmake --build ./build 88 | 89 | build-windows-conan: 90 | if: true 91 | runs-on: windows-latest 92 | 93 | steps: 94 | - uses: actions/checkout@v4 95 | 96 | - uses: TheMrMilchmann/setup-msvc-dev@v3 97 | with: 98 | arch: x64 99 | 100 | - name: Install Conan 101 | id: conan 102 | uses: turtlebrowser/get-conan@main 103 | 104 | - name: Init conan 105 | run: conan profile detect 106 | 107 | - name: Install dependencies 108 | shell: cmd 109 | run: conan install . -of build -s build_type=Release -o *:shared=False --build=missing 110 | 111 | - name: Build 112 | shell: cmd 113 | working-directory: ./build 114 | run: .\conanbuild.bat && cmake .. -G "Visual Studio 17 2022" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DBUILD_SHARED_LIBS=1 && cmake --build . --config Release 115 | 116 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | env: 9 | BUILD_TYPE: Release 10 | 11 | jobs: 12 | deb: 13 | if: true 14 | runs-on: ubuntu-latest 15 | container: 16 | image: debian:bookworm 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - name: Install dependencies 22 | run: apt-get -y update && apt-get install -y libgmp-dev build-essential cmake 23 | 24 | - name: Cmake 25 | run: cmake -G "Unix Makefiles" -B./build -DCMAKE_BUILD_TYPE=$BUILD_TYPE 26 | 27 | - name: Build 28 | run: cmake --build ./build 29 | 30 | - name: Package 31 | id: package 32 | working-directory: build 33 | run: | 34 | cpack -G "DEB" -D CPACK_PACKAGE_FILE_NAME=libbncsutil-dev_${{ github.ref_name }}_amd64 35 | 36 | - uses: actions/upload-artifact@v4 37 | with: 38 | retention-days: 1 39 | overwrite: true 40 | name: libbncsutil-dev_${{ github.ref_name }}_amd64.deb 41 | path: build/libbncsutil-dev_${{ github.ref_name }}_amd64.deb 42 | 43 | rpm: 44 | if: true 45 | runs-on: ubuntu-latest 46 | container: 47 | image: fedora:latest 48 | 49 | steps: 50 | - uses: actions/checkout@v4 51 | 52 | - name: Install dependencies 53 | run: dnf -y install gmp-devel make automake clang cmake rpm-build 54 | 55 | - name: Cmake 56 | run: cmake -G "Unix Makefiles" -B./build -DCMAKE_BUILD_TYPE=$BUILD_TYPE 57 | 58 | - name: Build 59 | run: cmake --build ./build 60 | 61 | - name: Package 62 | working-directory: build 63 | run: cpack -G "RPM" -D CPACK_PACKAGE_FILE_NAME=libbncsutil-devel-${{ github.ref_name }}.x86_64 64 | 65 | - uses: actions/upload-artifact@v4 66 | with: 67 | retention-days: 1 68 | overwrite: true 69 | name: libbncsutil-devel-${{ github.ref_name }}.x86_64.rpm 70 | path: build/libbncsutil-devel-${{ github.ref_name }}.x86_64.rpm 71 | 72 | dll_amd64: 73 | if: true 74 | runs-on: windows-latest 75 | 76 | steps: 77 | - uses: actions/checkout@v4 78 | 79 | - uses: TheMrMilchmann/setup-msvc-dev@v3 80 | with: 81 | arch: x64 82 | 83 | - name: Cache Conan 84 | uses: actions/cache@v3 85 | with: 86 | key: conan-windows-amd64-${{ hashFiles('conanfile.py') }} 87 | path: | 88 | ~/.conan2/p 89 | 90 | - name: Install Conan 91 | id: conan 92 | uses: turtlebrowser/get-conan@main 93 | 94 | - name: Init conan 95 | run: conan profile detect 96 | 97 | - name: Install dependencies 98 | shell: cmd 99 | run: conan install . -of build -s build_type=Release -o *:shared=False --build=missing 100 | 101 | - name: Build 102 | shell: cmd 103 | working-directory: ./build 104 | run: .\conanbuild.bat && cmake .. -G "Visual Studio 17 2022" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DBUILD_SHARED_LIBS=1 && cmake --build . --config Release 105 | 106 | - name: Create archive 107 | working-directory: ./build 108 | run: | 109 | New-Item -ItemType Directory -Path include/bncsutil -Force | Out-Null 110 | Copy-Item -Path '../src/bncsutil/*.h' -Destination include/bncsutil 111 | Compress-Archive -Path Release/* -DestinationPath bncsutil_${{ github.ref_name }}_amd64_dll.zip 112 | Compress-Archive -Path include -DestinationPath "bncsutil_${{ github.ref_name }}_amd64_dll.zip" -Update 113 | 114 | - uses: actions/upload-artifact@v4 115 | with: 116 | retention-days: 1 117 | overwrite: true 118 | name: bncsutil_${{ github.ref_name }}_amd64_dll.zip 119 | path: build/bncsutil_${{ github.ref_name }}_amd64_dll.zip 120 | 121 | dll_x86: 122 | if: true 123 | runs-on: windows-latest 124 | 125 | steps: 126 | - uses: actions/checkout@v4 127 | 128 | - uses: TheMrMilchmann/setup-msvc-dev@v3 129 | with: 130 | arch: x86 131 | 132 | - name: Install Conan 133 | id: conan 134 | uses: turtlebrowser/get-conan@main 135 | 136 | - name: Cache Conan 137 | uses: actions/cache@v3 138 | with: 139 | key: conan-windows-x86-${{ hashFiles('conanfile.py') }} 140 | path: | 141 | ~/.conan2/p 142 | 143 | - name: Init conan 144 | run: conan profile detect 145 | 146 | - name: Install dependencies 147 | shell: cmd 148 | run: conan install . -of build -s build_type=Release -s:h arch=x86 -o *:shared=False --build=missing 149 | 150 | - name: Build 151 | shell: cmd 152 | working-directory: ./build 153 | run: .\conanbuild.bat && cmake .. -DCMAKE_GENERATOR_PLATFORM=x86 -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DBUILD_SHARED_LIBS=1 && cmake --build . --config Release 154 | 155 | - name: Create archive 156 | working-directory: ./build 157 | run: | 158 | New-Item -ItemType Directory -Path include/bncsutil -Force | Out-Null 159 | Copy-Item -Path '../src/bncsutil/*.h' -Destination include/bncsutil 160 | Compress-Archive -Path Release/* -DestinationPath bncsutil_${{ github.ref_name }}_x86_dll.zip 161 | Compress-Archive -Path include -DestinationPath "bncsutil_${{ github.ref_name }}_x86_dll.zip" -Update 162 | 163 | - uses: actions/upload-artifact@v4 164 | with: 165 | retention-days: 1 166 | overwrite: true 167 | name: bncsutil_${{ github.ref_name }}_x86_dll.zip 168 | path: build/bncsutil_${{ github.ref_name }}_x86_dll.zip 169 | 170 | 171 | release: 172 | needs: [deb, rpm, dll_amd64, dll_x86] 173 | runs-on: ubuntu-latest 174 | 175 | steps: 176 | - name: Download deb 177 | uses: actions/download-artifact@v4 178 | with: 179 | name: libbncsutil-dev_${{ github.ref_name }}_amd64.deb 180 | 181 | - name: Download rpm 182 | uses: actions/download-artifact@v4 183 | with: 184 | name: libbncsutil-devel-${{ github.ref_name }}.x86_64.rpm 185 | 186 | - name: Download dll amd64 187 | uses: actions/download-artifact@v4 188 | with: 189 | name: bncsutil_${{ github.ref_name }}_amd64_dll.zip 190 | 191 | - name: Download dll x86 192 | uses: actions/download-artifact@v4 193 | with: 194 | name: bncsutil_${{ github.ref_name }}_x86_dll.zip 195 | 196 | - name: Create GitHub Release 197 | uses: softprops/action-gh-release@v1 198 | with: 199 | files: | 200 | libbncsutil-dev_${{ github.ref_name }}_amd64.deb 201 | libbncsutil-devel-${{ github.ref_name }}.x86_64.rpm 202 | bncsutil_${{ github.ref_name }}_amd64_dll.zip 203 | bncsutil_${{ github.ref_name }}_x86_dll.zip 204 | tag_name: ${{ github.ref_name }} 205 | env: 206 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.7z 2 | *.app 3 | *.bak 4 | *.class 5 | *.diff 6 | *.dll 7 | *.dmg 8 | *.err 9 | *.gz 10 | *.iso 11 | *.jar 12 | *.lib 13 | *.log 14 | *.o 15 | *.patch 16 | *.rar 17 | *.so 18 | *.swp 19 | *.tar 20 | *.tgz 21 | *.vi 22 | *.vim 23 | *.zip 24 | .DS_Store 25 | .Spotlight-V100 26 | .Trashes 27 | ._* 28 | CMakeCache.txt 29 | CMakeFiles/ 30 | CPackConfig.cmake 31 | CPackSourceConfig.cmake 32 | Debug/ 33 | Makefile 34 | Release/ 35 | Thumbs.db 36 | build/ 37 | cmake_install.cmake 38 | Findmpir.cmake 39 | conan.lock 40 | conanbuildinfo.txt 41 | conaninfo.txt 42 | graph_info.json 43 | CMakeUserPresets.json 44 | cmake-* 45 | .idea/ -------------------------------------------------------------------------------- /CMake/Modules/FindGMP.cmake: -------------------------------------------------------------------------------- 1 | # Try to find the GMP librairies 2 | # GMP_FOUND - system has GMP lib 3 | # GMP_INCLUDE_DIR - the GMP include directory 4 | # GMP_LIBRARIES - Libraries needed to use GMP 5 | 6 | if (GMP_INCLUDE_DIR AND GMP_LIBRARIES) 7 | set(GMP_FIND_QUIETLY TRUE) 8 | endif (GMP_INCLUDE_DIR AND GMP_LIBRARIES) 9 | 10 | find_path(GMP_INCLUDE_DIR NAMES gmp.h PATHS ${CMAKE_SOURCE_DIR}/depends/include) 11 | find_library(GMP_LIBRARIES NAMES gmp libgmp libgmp.so.10 PATHS ${CMAKE_SOURCE_DIR}/depends/lib ) 12 | 13 | MESSAGE(STATUS "GMP libs: " ${GMP_LIBRARIES} " " ${GMPXX_LIBRARIES} ) 14 | include(FindPackageHandleStandardArgs) 15 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMP DEFAULT_MSG GMP_INCLUDE_DIR GMP_LIBRARIES) 16 | mark_as_advanced(GMP_INCLUDE_DIR GMP_LIBRARIES) 17 | -------------------------------------------------------------------------------- /CMake/bncsutilConfig.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include("${CMAKE_CURRENT_LIST_DIR}/bncsutilTargets.cmake") 4 | 5 | set(bncsutil_FOUND TRUE) 6 | set(bncsutil_VERSION "@PROJECT_VERSION@") 7 | message(STATUS "Found bncsutil: ${bncsutil_VERSION}") -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.25) 2 | SET(VERSION_MAJOR "1") 3 | SET(VERSION_MINOR "4") 4 | SET(VERSION_PATCH "3") 5 | 6 | project(bncsutil VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") 7 | 8 | set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR} "${PROJECT_SOURCE_DIR}/CMake/Modules") 9 | message(${CMAKE_BINARY_DIR}) 10 | 11 | add_library(bncsutil SHARED) 12 | 13 | set(HEADERS 14 | "src/bncsutil/bncsutil.h" 15 | "src/bncsutil/bsha1.h" 16 | "src/bncsutil/buffer.h" 17 | "src/bncsutil/cdkeydecoder.h" 18 | "src/bncsutil/checkrevision.h" 19 | "src/bncsutil/decodekey.h" 20 | "src/bncsutil/file.h" 21 | "src/bncsutil/keytables.h" 22 | "src/bncsutil/libinfo.h" 23 | "src/bncsutil/ms_stdint.h" 24 | "src/bncsutil/mutil.h" 25 | "src/bncsutil/mutil_types.h" 26 | "src/bncsutil/nls.h" 27 | "src/bncsutil/oldauth.h" 28 | "src/bncsutil/pe.h" 29 | "src/bncsutil/sha1.h" 30 | "src/bncsutil/stack.h" 31 | ) 32 | 33 | set(SOURCES 34 | "src/bncsutil/bsha1.cpp" 35 | "src/bncsutil/cdkeydecoder.cpp" 36 | "src/bncsutil/checkrevision.cpp" 37 | "src/bncsutil/decodekey.cpp" 38 | "src/bncsutil/file.cpp" 39 | "src/bncsutil/libinfo.cpp" 40 | "src/bncsutil/nls.c" 41 | "src/bncsutil/oldauth.cpp" 42 | "src/bncsutil/pe.c" 43 | "src/bncsutil/sha1.c" 44 | "src/bncsutil/stack.c" 45 | ) 46 | 47 | target_sources(bncsutil PRIVATE ${SOURCES} ${HEADERS}) 48 | 49 | if (WIN32) 50 | option(USE_SYSTEM_LIBS "Use system libraries" OFF) 51 | else() 52 | option(USE_SYSTEM_LIBS "Use system libraries" ON) 53 | endif() 54 | 55 | if (CMAKE_GENERATOR_PLATFORM EQUAL "x86") 56 | set_target_properties(bncsutil PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") 57 | MESSAGE(STATUS "Excluding 64bit library paths from search.") 58 | set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS OFF) 59 | set(ARCH_DEB i386) 60 | set(ARCH_RPM i686) 61 | elseif (CMAKE_GENERATOR_PLATFORM EQUAL "x64") 62 | set_target_properties(bncsutil PROPERTIES COMPILE_FLAGS "-m64" LINK_FLAGS "-m64") 63 | set(ARCH_DEB amd64) 64 | set(ARCH_RPM x86_64) 65 | else() 66 | set(ARCH_DEB amd64) 67 | set(ARCH_RPM x86_64) 68 | endif() 69 | 70 | if (USE_SYSTEM_LIBS) 71 | message("Using system dependencies") 72 | find_package(GMP REQUIRED) 73 | target_include_directories(bncsutil PRIVATE src ${GMP_INCLUDE_DIR}) 74 | target_link_libraries(bncsutil ${GMP_LIBRARIES}) 75 | else() 76 | message("Using conan dependencies") 77 | find_package(gmp REQUIRED) 78 | target_include_directories(bncsutil PRIVATE src gmp::gmp) 79 | target_link_libraries(bncsutil PRIVATE gmp::gmp) 80 | endif() 81 | 82 | set_target_properties(bncsutil PROPERTIES OUTPUT_NAME bncsutil) 83 | 84 | if(UNIX) 85 | set_target_properties(bncsutil PROPERTIES VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") 86 | set_target_properties(bncsutil PROPERTIES SOVERSION 1) 87 | 88 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -Wno-multichar -fPIC") 89 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -Wno-multichar -fPIC") 90 | endif() 91 | 92 | if (WIN32) 93 | add_definitions(-D_CRT_SECURE_NO_WARNINGS -DMUTIL_LIB_BUILD) 94 | endif() 95 | 96 | if (MSVC) 97 | set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "bncsutil") 98 | endif() 99 | 100 | include(CMakePackageConfigHelpers) 101 | 102 | install(TARGETS bncsutil 103 | EXPORT bncsutilTargets 104 | RUNTIME DESTINATION bin 105 | LIBRARY DESTINATION lib 106 | ARCHIVE DESTINATION lib 107 | INCLUDES DESTINATION include 108 | ) 109 | 110 | install(FILES ${HEADERS} DESTINATION include/bncsutil) 111 | 112 | install(EXPORT bncsutilTargets 113 | FILE bncsutilTargets.cmake 114 | NAMESPACE bncsutil:: 115 | DESTINATION lib/cmake/bncsutil 116 | ) 117 | 118 | configure_package_config_file( 119 | "${CMAKE_CURRENT_SOURCE_DIR}/CMake/bncsutilConfig.cmake.in" 120 | "${CMAKE_CURRENT_BINARY_DIR}/bncsutilConfig.cmake" 121 | INSTALL_DESTINATION lib/cmake/bncsutil 122 | ) 123 | 124 | write_basic_package_version_file( 125 | "${CMAKE_CURRENT_BINARY_DIR}/bncsutilConfigVersion.cmake" 126 | VERSION ${PROJECT_VERSION} 127 | COMPATIBILITY AnyNewerVersion 128 | ) 129 | 130 | install(FILES 131 | "${CMAKE_CURRENT_BINARY_DIR}/bncsutilConfig.cmake" 132 | "${CMAKE_CURRENT_BINARY_DIR}/bncsutilConfigVersion.cmake" 133 | DESTINATION lib/cmake/bncsutil 134 | ) 135 | 136 | #CPack configuration 137 | SET(CPACK_GENERATOR "DEB" "RPM") 138 | SET(CPACK_PACKAGE_NAME "bncsutil") 139 | SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Battle.Net Chat Service Utility") 140 | SET(CPACK_PACKAGE_VENDOR "bncsutil") 141 | SET(CPACK_PACKAGE_DESCRIPTION "\ 142 | This will install the library to /usr/local/lib and header files to /usr/local/include.\n \ 143 | Make sure these directories are in your library and include paths. \ 144 | ") 145 | SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") 146 | SET(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}") 147 | SET(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}") 148 | SET(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PATCH}") 149 | set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/local") 150 | 151 | #DEB configuration 152 | SET(CPACK_DEBIAN_PACKAGE_SECTION "libs") 153 | SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/BNETDocs/bncsutil") 154 | SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "imbacen@gmail.com") 155 | SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${ARCH_DEB}) 156 | SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libgmp10") 157 | 158 | #RPM configuration 159 | SET(CPACK_RPM_PACKAGE_RELEASE 1) 160 | SET(CPACK_RPM_PACKAGE_LICENSE "LGPL-2.1") 161 | SET(CPACK_RPM_PACKAGE_GROUP "bncsutil") 162 | SET(CPACK_RPM_PACKAGE_URL "https://github.com/BNETDocs/bncsutil") 163 | SET(CPACK_RPM_PACKAGE_REQUIRES "gmp") 164 | SET(CPACK_RPM_PACKAGE_ARCHITECTURE ${ARCH_RPM}) 165 | 166 | INCLUDE(CPack) 167 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BNCSUtil 2 | 3 | [![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/BNETDocs/bncsutil/cmake.yml?branch=master&style=flat)](https://github.com/BNETDocs/bncsutil/actions?query=workflow%3ACMake) 4 | [![GitHub top language](https://img.shields.io/github/languages/top/BNETDocs/bncsutil?style=flat)](https://github.com/BNETDocs/bncsutil) 5 | ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/BNETDocs/bncsutil?style=flat) 6 | [![License Badge](https://img.shields.io/github/license/BNETDocs/bncsutil?style=flat)](https://github.com/BNETDocs/bncsutil/blob/master/COPYING) 7 | [![GitHub release (latest SemVer including pre-releases)](https://img.shields.io/github/v/release/BNETDocs/bncsutil?include_prereleases&label=latest%20release&style=flat)](https://github.com/BNETDocs/bncsutil/releases/latest) 8 | [![GitHub All Releases](https://img.shields.io/github/downloads/BNETDocs/bncsutil/total?style=flat)](https://github.com/BNETDocs/bncsutil/releases/latest) 9 | 10 | **BNCSUtil** is the **B**attle.**N**et **C**hat **S**ervice **Util**ity which 11 | aids applications trying to logon to Classic Battle.net™ using the binary 12 | protocol. Specifically, BNCSUtil has functions that help with the cryptography 13 | of game versions, keys, and passwords. 14 | 15 | BNCSUtil was originally written by Eric Naeseth (shadypalm88) and has since 16 | been maintained over the course of several years by the open source Battle.net community. 17 | 18 | # Usage 19 | `#include ` and link against `bncsutil.lib` or `libbncsutil.so`. 20 | 21 | For CMake add: 22 | ``` 23 | find_package(bncsutil REQUIRED) 24 | target_link_libraries(mytarget PRIVATE bncsutil::bncsutil) 25 | ``` 26 | 27 | # Building 28 | 29 | To force a specific build (32bit or 64bit) add `-DCMAKE_GENERATOR_PLATFORM=x86` or `-DCMAKE_GENERATOR_PLATFORM=x64` to CMake flags. 30 | 31 | Change `BUILD_SHARED_LIBS` to build the library as static or shared. 32 | 33 | ## Windows Visual Studio 2022 34 | 35 | Conan is used to install dependencies. GMP can't be installed as a shared library due to a bug. Mpir dependency option will be re-introduced once it is uploaded to conan index v2 (MR pending). 36 | 37 | In `cmd` or Visual Studio dev console run: 38 | 39 | ### amd64 40 | ``` 41 | "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat" x64 42 | conan install . -of build -s build_type=Release -o *:shared=False --build=missing 43 | cd build 44 | .\conanbuild.bat 45 | cmake .. -G "Visual Studio 17 2022" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DBUILD_SHARED_LIBS=1 46 | cmake --build . --config Release 47 | ``` 48 | 49 | ### x86 50 | ``` 51 | "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat" x86 52 | conan install . -of build -s build_type=Release -s:h arch=x86 -o *:shared=False --build=missing 53 | cd build 54 | .\conanbuild.bat 55 | cmake .. -G "Visual Studio 17 2022" -DCMAKE_GENERATOR_PLATFORM=x86 -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DBUILD_SHARED_LIBS=1 56 | cmake --build . --config Release 57 | ``` 58 | 59 | Alternatively open `build/bncsutil.sln` and build from Visual Studio. 60 | 61 | ## Linux 62 | 63 | ### Using system dependencies 64 | Install `libgmp-dev` on deb distros or `gmp-devel` on rpm distros. For 32bit builds, CMake will not warn you if you are missing 32bit glibc and GMP, you must install them manually first (CentOS/Fedora: `glibc-devel.i686` and `gmp-devel.i686`). 65 | 66 | ``` 67 | cmake -G "Unix Makefiles" -B./build 68 | cd build 69 | cmake --build . --target install --config Release 70 | ``` 71 | 72 | ### Using conan 73 | If you are using pyenv or building python3 from source, make sure you have `libbz2-dev` and `liblzma-dev` installed first or conan will fail to unpack dependencies. 74 | 75 | ``` 76 | conan install . -of build -s build_type=Release --build=missing 77 | cd build 78 | bash conanbuild.sh 79 | cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DUSE_SYSTEM_LIBS=0 80 | cmake --build . --config Release 81 | ``` 82 | 83 | ## .deb and .rpm packages 84 | After invoking CMake, cd to build folder and generate them with `cpack -G "DEB"` and `cpack -G "RPM"`. 85 | You can then use `gdebi` to do a local install of .deb with automatic dependency resolution or `yum localinstall` on rpm distros. For dnf it's `dnf install .rpm`. 86 | 87 | Note that this is a "development" package which also includes header files. 88 | 89 | Library installs to `/usr/local/lib`, include files in `/usr/local/include/bncsutil`. 90 | 91 | Packages are also available for download from github releases built on Debian Bookworm and Fedora latest. 92 | 93 | # Development with CLion 94 | 1. Run conan from cli as per build instructions above 95 | 2. Open the project 96 | 3. Tools -> CMake -> Change Project Root -> build 97 | 4. Settings -> Build, Execution, Deployment -> CMake -> Add at least this cmake option: -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake 98 | 99 | -------------------------------------------------------------------------------- /conanfile.py: -------------------------------------------------------------------------------- 1 | from conan import ConanFile 2 | from conan.tools.files import copy 3 | from conan.tools.files import rename 4 | import os 5 | 6 | class Bncsutil(ConanFile): 7 | settings = "os", "compiler", "build_type", "arch" 8 | generators = "CMakeDeps", "CMakeToolchain" 9 | 10 | requires = ( 11 | "gmp/6.3.0", 12 | ) 13 | 14 | def generate(self): 15 | # Workaround for a conan bug producing wrongly named libraries.. 16 | if self.settings.os == "Windows": 17 | gmp_libdir = self.dependencies["gmp"].cpp_info.libdir 18 | gmp_from_name = f"{gmp_libdir}\libgmp.a" 19 | gmp_to_name = f"{gmp_libdir}\gmp.lib" 20 | gmpxx_from_name = f"{gmp_libdir}\libgmpxx.a" 21 | gmpxx_to_name = f"{gmp_libdir}\gmpxx.lib" 22 | 23 | if os.path.isfile(gmp_from_name): 24 | print("Renaming " + gmp_from_name + " to " + gmp_to_name) 25 | rename(self, gmp_from_name, gmp_to_name) 26 | if os.path.isfile(gmpxx_from_name): 27 | print("Renaming " + gmpxx_from_name + " to " + gmpxx_to_name) 28 | rename(self, gmpxx_from_name, gmpxx_to_name) 29 | 30 | for dep in self.dependencies.values(): 31 | if dep.cpp_info.libdirs: 32 | copy(self, "*.lib", dep.cpp_info.libdirs[0], self.build_folder) 33 | if dep.cpp_info.bindirs: 34 | copy(self, "*.dll", dep.cpp_info.bindirs[0], self.build_folder) -------------------------------------------------------------------------------- /src/bncsutil/bncsutil.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Common Interface 8 | * November 20, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef BNCSUTIL_BNCSUTIL_H_INCLUDED 27 | #define BNCSUTIL_BNCSUTIL_H_INCLUDED 28 | 29 | #include /* Myriad Utility Header */ 30 | #include /* CheckRevision / EXE info */ 31 | #include /* Broken SHA-1 */ 32 | #include /* Old Logon System */ 33 | #include /* CD-Key Decoding C wrappers */ 34 | #ifdef __cplusplus 35 | #include /* CD-Key Decoding Class */ 36 | #endif /* __cplusplus */ 37 | #include /* New Logon System */ 38 | #include /* BNCSutil Library Information */ 39 | 40 | #endif /* BNCSUTIL_BNCSUTIL_H_INCLUDED */ 41 | -------------------------------------------------------------------------------- /src/bncsutil/bsha1.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Broken SHA-1 Implementation 8 | * October 23, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #define USE_NEW_BSHA1 0 31 | 32 | #define BSHA_IC1 0x67452301lu 33 | #define BSHA_IC2 0xEFCDAB89lu 34 | #define BSHA_IC3 0x98BADCFElu 35 | #define BSHA_IC4 0x10325476lu 36 | #define BSHA_IC5 0xC3D2E1F0lu 37 | 38 | #define BSHA_OC1 0x5A827999lu 39 | #define BSHA_OC2 0x6ED9EBA1lu 40 | #define BSHA_OC3 0x70E44324lu 41 | #define BSHA_OC4 0x359D3E2Alu 42 | 43 | #if !USE_NEW_BSHA1 44 | # define BSHA_COP e = d; d = c; c = ROL(b, 30); b = a; a = g; 45 | #else 46 | # define BSHA_N_COP t[4] = t[3]; t[3] = t[2]; t[2] = ROL(t[1], 30); \ 47 | t[1] = t[0]; t[0] = x 48 | #endif 49 | 50 | #if !USE_NEW_BSHA1 51 | #define BSHA_OP1(a, b, c, d, e, f, g) g = LSB4(f) + ROL(a, 5) + e + \ 52 | ((b & c) | (~b & d)) + BSHA_OC1; BSHA_COP 53 | #define BSHA_OP2(a, b, c, d, e, f, g) g = (d ^ c ^ b) + e + ROL(g, 5) + \ 54 | LSB4(f) + BSHA_OC2; BSHA_COP 55 | #define BSHA_OP3(a, b, c, d, e, f, g) g = LSB4(f) + ROL(g, 5) + e + \ 56 | ((c & b) | (d & c) | (d & b)) - BSHA_OC3; BSHA_COP 57 | #define BSHA_OP4(a, b, c, d, e, f, g) g = (d ^ c ^ b) + e + ROL(g, 5) + \ 58 | LSB4(f) - BSHA_OC4; BSHA_COP 59 | 60 | #else 61 | 62 | #define BSHA_N_OP1() x = LSB4(*p++) + ROL(t[0], 5) + t[4] + \ 63 | ((t[1] & t[2]) | (~t[1] & t[3])) + BSHA_OC1; BSHA_N_COP 64 | #define BSHA_N_OP2() x = (t[3] ^ t[2] ^ t[1]) + t[4] + ROL(x, 5) + \ 65 | LSB4(*p++) + BSHA_OC2; BSHA_N_COP 66 | #define BSHA_N_OP3() x = LSB4(*p++) + ROL(x, 5) + t[4] + \ 67 | ((t[2] & t[1]) | (t[3] & t[2]) | (t[3] & t[1])) - BSHA_OC3; BSHA_N_COP 68 | #define BSHA_N_OP4() x = (t[3] ^ t[2] ^ t[1]) + t[4] + ROL(x, 5) + \ 69 | LSB4(*p++) - BSHA_OC4; BSHA_N_COP 70 | #endif 71 | 72 | #if USE_NEW_BSHA1 73 | MEXP(void) calcHashBuf(const char* input, unsigned int length, char* result) { 74 | uint32_t vals[5]; 75 | uint32_t t[5]; // a, b, c, d, e 76 | uint32_t buf[0x50]; 77 | uint32_t* p; 78 | uint32_t x; 79 | const char* in = input; 80 | unsigned int i, j; 81 | unsigned int sub_length; 82 | 83 | /* Initializer Values */ 84 | p = vals; 85 | *p++ = BSHA_IC1; 86 | *p++ = BSHA_IC2; 87 | *p++ = BSHA_IC3; 88 | *p++ = BSHA_IC4; 89 | *p++ = BSHA_IC5; 90 | 91 | memset(buf, 0, 320); // zero buf 92 | 93 | /* Process input in chunks. */ 94 | for (i = 0; i < length; i += 0x40) { 95 | sub_length = length - i; 96 | 97 | /* Maximum chunk size is 0x40 (64) bytes. */ 98 | if (sub_length > 0x40) 99 | sub_length = 0x40; 100 | 101 | memcpy(buf, in, sub_length); 102 | in += sub_length; 103 | 104 | /* If necessary, pad with zeroes to 64 bytes. */ 105 | if (sub_length < 0x40) 106 | memset(buf + sub_length, 0, 0x40 - sub_length); 107 | 108 | for (j = 0; j < 64; j++) { 109 | buf[j + 16] = 110 | LSB4(ROL(1, LSB4(buf[j] ^ buf[j+8] ^ buf[j+2] ^ buf[j+13]) % 32)); 111 | } 112 | 113 | memcpy(t, vals, 20); 114 | p = buf; 115 | 116 | /* It's a kind of magic. */ 117 | BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); 118 | BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); 119 | 120 | BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); 121 | BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); 122 | 123 | BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); 124 | BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); 125 | 126 | BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); 127 | BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); 128 | 129 | vals[0] += t[0]; 130 | vals[1] += t[1]; 131 | vals[2] += t[2]; 132 | vals[3] += t[3]; 133 | vals[4] += t[4]; 134 | } 135 | 136 | /* Return result. */ 137 | memcpy(result, vals, 20); 138 | } 139 | 140 | #else 141 | 142 | MEXP(void) calcHashBuf(const char* input, size_t length, char* result) { 143 | int i; 144 | uint32_t a, b, c, d, e, g; 145 | uint32_t* ldata; 146 | char data[1024]; 147 | memset(data, 0, 1024); 148 | memcpy(data, input, length); 149 | ldata = (uint32_t*) data; 150 | 151 | for (i = 0; i < 64; i++) { 152 | ldata[i + 16] = 153 | LSB4(ROL(1, LSB4(ldata[i] ^ ldata[i+8] ^ ldata[i+2] ^ ldata[i+13]) % 32)); 154 | } 155 | 156 | //dumpbuf(data, 1024); 157 | 158 | a = BSHA_IC1; 159 | b = BSHA_IC2; 160 | c = BSHA_IC3; 161 | d = BSHA_IC4; 162 | e = BSHA_IC5; 163 | g = 0; 164 | 165 | // Loops unrolled. 166 | BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) 167 | BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) 168 | BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) 169 | BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) 170 | BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) 171 | BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) 172 | BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) 173 | BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) 174 | BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) 175 | BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) 176 | 177 | BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) 178 | BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) 179 | BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) 180 | BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) 181 | BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) 182 | BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) 183 | BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) 184 | BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) 185 | BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) 186 | BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) 187 | 188 | BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) 189 | BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) 190 | BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) 191 | BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) 192 | BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) 193 | BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) 194 | BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) 195 | BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) 196 | BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) 197 | BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) 198 | 199 | BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) 200 | BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) 201 | BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) 202 | BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) 203 | BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) 204 | BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) 205 | BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) 206 | BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) 207 | BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) 208 | BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) 209 | 210 | ldata = (uint32_t*) result; 211 | ldata[0] = LSB4(BSHA_IC1 + a); 212 | ldata[1] = LSB4(BSHA_IC2 + b); 213 | ldata[2] = LSB4(BSHA_IC3 + c); 214 | ldata[3] = LSB4(BSHA_IC4 + d); 215 | ldata[4] = LSB4(BSHA_IC5 + e); 216 | ldata = NULL; 217 | } 218 | #endif 219 | -------------------------------------------------------------------------------- /src/bncsutil/bsha1.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Broken SHA-1 Interface 8 | * October 23, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef BSHA1_H 27 | #define BSHA1_H 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * calcHashBuf 35 | * 36 | * Calculates a "Broken SHA-1" hash of data. 37 | * 38 | * Paramaters: 39 | * data: The data to hash. 40 | * length: The length of data. 41 | * hash: Buffer, at least 20 bytes in length, to receive the hash. 42 | */ 43 | MEXP(void) calcHashBuf(const char* data, size_t length, char* hash); 44 | 45 | /* 46 | * New implementation. Broken. No plans to fix. 47 | */ 48 | MEXP(void) bsha1_hash(const char* input, unsigned int length, char* result); 49 | 50 | #ifdef __cplusplus 51 | } // extern "C" 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/bncsutil/buffer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Message Buffers 8 | * January 11, 2006 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef BUFFER_H 27 | #define BUFFER_H 28 | 29 | #include 30 | 31 | typedef struct msg_buffer *msg_buffer_t; 32 | typedef struct msg_buffer_impl *msg_buffer_impl_t; 33 | typedef struct msg_reader *msg_reader_t; 34 | typedef struct msg_reader_impl *msg_reader_impl_t; 35 | 36 | // Callbacks 37 | 38 | /** 39 | * Called to determine the number of bytes at the beginning of an output 40 | * buffer to reserve for a message/packet header. 41 | */ 42 | typedef size_t __stdcall (*buffer_bytes_to_reserve)(); 43 | 44 | /** 45 | * Called to generate the header on an outgoing packet. 46 | */ 47 | typedef int __stdcall (*buffer_create_header)(msg_buffer_t); 48 | 49 | 50 | /** 51 | * Creates a new generic buffer for an outgoing packet. 52 | */ 53 | msg_buffer_t create_buffer(size_t initial_size); 54 | 55 | /** 56 | * Creates a new BNCS buffer. 57 | */ 58 | msg_buffer_t create_bncs_buffer(size_t initial_size); 59 | 60 | /** 61 | * Destroys a message buffer. 62 | */ 63 | void destroy_buffer(msg_buffer_t); 64 | 65 | // Adders 66 | 67 | void buffer_add_8(msg_buffer_t, int8_t); 68 | void buffer_add_u8(msg_buffer_t, uint8_t); 69 | void buffer_add_16(msg_buffer_t, int16_t); 70 | void buffer_add_u16(msg_buffer_t, uint16_t); 71 | void buffer_add_32(msg_buffer_t, int32_t); 72 | void buffer_add_u32(msg_buffer_t, uint32_t); 73 | 74 | msg_reader_t create_reader(size_t initial_size); 75 | 76 | #endif /* BUFFER_H */ 77 | -------------------------------------------------------------------------------- /src/bncsutil/cdkeydecoder.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * CD-Key Decoder Interface 8 | * September 29, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef BNCSUTIL_CDKEYDECODER_H 27 | #define BNCSUTIL_CDKEYDECODER_H 28 | 29 | #include 30 | 31 | /** 32 | * Internal key type constants. 33 | */ 34 | #define KEY_STARCRAFT 1 35 | #define KEY_DIABLO2 2 36 | #define KEY_WARCRAFT2 2 /* [sic] */ 37 | #define KEY_WARCRAFT3 3 38 | 39 | MCEXP(CDKeyDecoder) { 40 | protected: 41 | char* cdkey; 42 | int initialized; 43 | int keyOK; 44 | size_t keyLen; 45 | char* keyHash; 46 | size_t hashLen; 47 | int keyType; 48 | unsigned long value1; 49 | unsigned long value2; 50 | unsigned long product; 51 | char* w3value2; 52 | 53 | int processStarCraftKey(); 54 | int processWarCraft2Key(); 55 | int processWarCraft3Key(); 56 | 57 | void decodeKeyTable(int* keyTable); 58 | 59 | inline char getHexValue(int v); 60 | inline int getNumValue(char v); 61 | 62 | inline void mult(int r, int x, int* a, int dcByte); 63 | 64 | public: 65 | /** 66 | * Creates a new CD-key decoder object. 67 | * Not really useful unless subclassed. 68 | */ 69 | CDKeyDecoder(); 70 | 71 | CDKeyDecoder(const char* cd_key); 72 | 73 | /** 74 | * Creates a new CD-key decoder object, using the specified key. 75 | * keyLength should be the length of the key, NOT INCLUDING the 76 | * null-terminator. Applications should use isKeyValid after using 77 | * this constructor to check the validity of the provided key. 78 | */ 79 | CDKeyDecoder(const char* cdKey, size_t keyLength); 80 | 81 | virtual ~CDKeyDecoder(); 82 | 83 | int isKeyValid(); 84 | int getVal2Length(); 85 | uint32_t getProduct(); 86 | uint32_t getVal1(); 87 | uint32_t getVal2(); 88 | int getLongVal2(char* out); 89 | 90 | /** 91 | * Calculates the CD-Key hash for use in SID_AUTH_CHECK (0x51) 92 | * Returns the length of the generated hash; call getHash and pass 93 | * it a character array that is at least this size. Returns 0 on failure. 94 | * 95 | * Note that clientToken and serverToken will be added to the buffer and 96 | * hashed as-is, regardless of system endianness. It is assumed that 97 | * the program's extraction of the server token does not change its 98 | * endianness, and since the client token is generated by the client, 99 | * endianness is not a factor. 100 | */ 101 | size_t calculateHash(uint32_t clientToken, uint32_t serverToken); 102 | 103 | /** 104 | * Places the calculated CD-key hash in outputBuffer. You must call 105 | * calculateHash before getHash. Returns the length of the hash 106 | * that was copied to outputBuffer, or 0 on failure. The hash is 107 | * not deleted after getHash is run; subsequent calls to getHash 108 | * will still function. 109 | */ 110 | size_t getHash(char* outputBuffer); 111 | }; 112 | 113 | #endif /* BNCSUTIL_CDKEYDECODER_H */ 114 | -------------------------------------------------------------------------------- /src/bncsutil/checkrevision.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * CheckRevision Implementation 8 | * November 12, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef MOS_WINDOWS 35 | #include 36 | #else 37 | #include 38 | #include 39 | #include 40 | #include 41 | #endif 42 | 43 | #ifndef HIWORD 44 | #define HIWORD(l) ((uint16_t) ((l) >> 16)) 45 | #endif 46 | 47 | #ifndef LOWORD 48 | #define LOWORD(l) ((uint16_t) ((l) & 0xFFFF)) 49 | #endif 50 | 51 | #ifdef HAVE__SNPRINTF 52 | #define snprintf _snprintf 53 | #endif 54 | 55 | // BNCSutil - CheckRevision - GetNumber 56 | #define BUCR_GETNUM(ch) (((ch) == 'S') ? 3 : ((ch) - 'A')) 57 | // BNCSutil - CheckRevision - IsNumber 58 | #define BUCR_ISNUM(ch) (((ch) >= '0') && ((ch) <= '9')) 59 | 60 | #include 61 | 62 | #ifdef __cplusplus 63 | extern "C" { 64 | #endif 65 | 66 | 67 | std::vector checkrevision_seeds; 68 | void initialize_checkrevision_seeds() 69 | { 70 | static bool run = false; 71 | 72 | if (run) 73 | return; 74 | 75 | run = true; 76 | 77 | checkrevision_seeds.reserve(8); 78 | 79 | checkrevision_seeds.push_back(0xE7F4CB62); 80 | checkrevision_seeds.push_back(0xF6A14FFC); 81 | checkrevision_seeds.push_back(0xAA5504AF); 82 | checkrevision_seeds.push_back(0x871FCDC2); 83 | checkrevision_seeds.push_back(0x11BF6A18); 84 | checkrevision_seeds.push_back(0xC57292E6); 85 | checkrevision_seeds.push_back(0x7927D27E); 86 | checkrevision_seeds.push_back(0x2FEC8733); 87 | } 88 | 89 | MEXP(long) get_mpq_seed(int mpq_number) 90 | { 91 | if (((size_t) mpq_number) >= checkrevision_seeds.size()) { 92 | //bncsutil_debug_message_a("error: no known revision check seed for " 93 | // "MPQ#%u", mpq_number); 94 | return 0; 95 | } 96 | 97 | return checkrevision_seeds[mpq_number]; 98 | } 99 | 100 | MEXP(long) set_mpq_seed(int mpq_number, long new_seed) 101 | { 102 | long ret; 103 | 104 | if (((size_t) mpq_number) >= checkrevision_seeds.size()) { 105 | ret = 0; 106 | checkrevision_seeds.reserve((size_t) mpq_number); 107 | } else { 108 | ret = checkrevision_seeds[mpq_number]; 109 | } 110 | 111 | checkrevision_seeds[mpq_number] = new_seed; 112 | return ret; 113 | } 114 | 115 | MEXP(int) extractMPQNumber(const char* mpqName) 116 | { 117 | const char* n; 118 | int mpqNum; 119 | if (mpqName == NULL) 120 | return -1; 121 | if ((n = (const char*) std::strchr(mpqName, '.')) == NULL) 122 | return -1; 123 | // extract int value of version number 124 | mpqNum = atoi(n - 1); 125 | return mpqNum; 126 | } 127 | 128 | const char* get_basename(const char* file_name) 129 | { 130 | const char* base; 131 | 132 | for (base = (file_name + strlen(file_name)); base >= file_name; base--) { 133 | if (*base == '\\' || *base == '/') 134 | break; 135 | } 136 | 137 | return ++base; 138 | } 139 | 140 | MEXP(int) checkRevision(const char* formula, const char* files[], int numFiles, 141 | int mpqNumber, unsigned long* checksum) 142 | { 143 | uint64_t values[4]; 144 | long ovd[4], ovs1[4], ovs2[4]; 145 | char ops[4]; 146 | const char* token; 147 | int curFormula = 0; 148 | file_t f; 149 | uint8_t* file_buffer; 150 | uint32_t* dwBuf; 151 | uint32_t* current; 152 | size_t seed_count; 153 | 154 | #if DEBUG 155 | int i; 156 | bncsutil_debug_message_a("checkRevision(\"%s\", {", formula); 157 | for (i = 0; i < numFiles; i++) { 158 | bncsutil_debug_message_a("\t\"%s\",", files[i]); 159 | } 160 | bncsutil_debug_message_a("}, %d, %d, %p);", numFiles, mpqNumber, checksum); 161 | #endif 162 | 163 | if (!formula || !files || numFiles == 0 || mpqNumber < 0 || !checksum) { 164 | //bncsutil_debug_message("error: checkRevision() parameter sanity check " 165 | // "failed"); 166 | return 0; 167 | } 168 | 169 | seed_count = checkrevision_seeds.size(); 170 | if (seed_count == 0) { 171 | initialize_checkrevision_seeds(); 172 | seed_count = checkrevision_seeds.size(); 173 | } 174 | 175 | if (seed_count <= (size_t) mpqNumber) { 176 | //bncsutil_debug_message_a("error: no revision check seed value defined " 177 | // "for MPQ number %d", mpqNumber); 178 | return 0; 179 | } 180 | 181 | token = formula; 182 | while (token && *token) { 183 | if (*(token + 1) == '=') { 184 | int variable = BUCR_GETNUM(*token); 185 | if (variable < 0 || variable > 3) { 186 | //bncsutil_debug_message_a("error: Unknown revision check formula" 187 | // " variable %c", *token); 188 | return 0; 189 | } 190 | 191 | token += 2; // skip over equals sign 192 | if (BUCR_ISNUM(*token)) { 193 | values[variable] = ATOL64(token); 194 | } else { 195 | if (curFormula > 3) { 196 | // more than 4 operations? bloody hell. 197 | //bncsutil_debug_message("error: Revision check formula" 198 | // " contains more than 4 operations; unsupported."); 199 | return 0; 200 | } 201 | ovd[curFormula] = variable; 202 | ovs1[curFormula] = BUCR_GETNUM(*token); 203 | ops[curFormula] = *(token + 1); 204 | ovs2[curFormula] = BUCR_GETNUM(*(token + 2)); 205 | curFormula++; 206 | } 207 | } 208 | 209 | for (; *token != 0; token++) { 210 | if (*token == ' ') { 211 | token++; 212 | break; 213 | } 214 | } 215 | } 216 | 217 | // Actual hashing (yay!) 218 | // "hash A by the hashcode" 219 | values[0] ^= checkrevision_seeds[mpqNumber]; 220 | 221 | for (int i = 0; i < numFiles; i++) { 222 | size_t file_len, remainder, rounded_size, buffer_size; 223 | 224 | f = file_open(files[i], FILE_READ); 225 | if (!f) { 226 | //bncsutil_debug_message_a("error: Failed to open file %s", 227 | // files[i]); 228 | return 0; 229 | } 230 | 231 | file_len = file_size(f); 232 | remainder = file_len % 1024; 233 | rounded_size = file_len - remainder; 234 | 235 | file_buffer = (uint8_t*) file_map(f, file_len, 0); 236 | if (!file_buffer) { 237 | file_close(f); 238 | //bncsutil_debug_message_a("error: Failed to map file %s into memory", 239 | // files[i]); 240 | return 0; 241 | } 242 | 243 | if (remainder == 0) { 244 | // Mapped buffer may be used directly, without padding. 245 | dwBuf = (uint32_t*) file_buffer; 246 | buffer_size = file_len; 247 | } else { 248 | // Must be padded to nearest KB. 249 | size_t extra = 1024 - remainder; 250 | uint8_t pad = (uint8_t) 0xFF; 251 | uint8_t* pad_dest; 252 | 253 | buffer_size = file_len + extra; 254 | dwBuf = (uint32_t*) malloc(buffer_size); 255 | if (!dwBuf) { 256 | //bncsutil_debug_message_a("error: Failed to allocate %d bytes " 257 | // "of memory as a temporary buffer", buffer_size); 258 | file_unmap(f, file_buffer); 259 | file_close(f); 260 | return 0; 261 | } 262 | 263 | memcpy(dwBuf, file_buffer, file_len); 264 | file_unmap(f, file_buffer); 265 | file_buffer = (uint8_t*) 0; 266 | 267 | pad_dest = ((uint8_t*) dwBuf) + file_len; 268 | for (size_t j = file_len; j < buffer_size; j++) { 269 | *pad_dest++ = pad--; 270 | } 271 | 272 | } 273 | 274 | current = dwBuf; 275 | for (size_t j = 0; j < buffer_size; j += 4) { 276 | values[3] = LSB4(*(current++)); 277 | for (int k = 0; k < curFormula; k++) { 278 | switch (ops[k]) { 279 | case '+': 280 | values[ovd[k]] = values[ovs1[k]] + values[ovs2[k]]; 281 | break; 282 | case '-': 283 | values[ovd[k]] = values[ovs1[k]] - values[ovs2[k]]; 284 | break; 285 | case '^': 286 | values[ovd[k]] = values[ovs1[k]] ^ values[ovs2[k]]; 287 | break; 288 | case '*': 289 | // well, you never know 290 | values[ovd[k]] = values[ovs1[k]] * values[ovs2[k]]; 291 | break; 292 | case '/': 293 | // well, you never know 294 | values[ovd[k]] = values[ovs1[k]] / values[ovs2[k]]; 295 | break; 296 | default: 297 | // unrecognized operation 298 | // shit 299 | file_unmap(f, dwBuf); 300 | file_close(f); 301 | return 0; 302 | } 303 | } 304 | } 305 | 306 | if (file_buffer) 307 | file_unmap(f, file_buffer); 308 | else if (dwBuf && file_buffer == 0) 309 | free(dwBuf); // padded buffer 310 | file_close(f); 311 | } 312 | 313 | *checksum = (unsigned long) LSB4(values[2]); 314 | #if DEBUG 315 | bncsutil_debug_message_a("\tChecksum = %lu", *checksum); 316 | #endif 317 | return 1; 318 | } 319 | 320 | MEXP(int) checkRevisionFlat(const char* valueString, const char* file1, 321 | const char* file2, const char* file3, int mpqNumber, unsigned long* checksum) 322 | { 323 | const char* files[] = 324 | {file1, file2, file3}; 325 | return checkRevision(valueString, files, 3, mpqNumber, 326 | checksum); 327 | } 328 | 329 | MEXP(int) getExeInfo(const char* file_name, char* exe_info, 330 | size_t exe_info_size, uint32_t* version, int platform) 331 | { 332 | const char* base = (char*) 0; 333 | unsigned long file_size; 334 | FILE* f = (FILE*) 0; 335 | int ret; 336 | #ifdef MOS_WINDOWS 337 | HANDLE hFile; 338 | FILETIME ft; 339 | SYSTEMTIME st; 340 | LPBYTE buf; 341 | VS_FIXEDFILEINFO* ffi; 342 | DWORD infoSize, bytesRead; 343 | #else 344 | cm_pe_t pe; 345 | cm_pe_resdir_t* root; 346 | cm_pe_resdir_t* dir; 347 | cm_pe_version_t ffi; 348 | size_t i; 349 | struct stat st; 350 | struct tm* time; 351 | #endif 352 | 353 | if (!file_name || !exe_info || !exe_info_size || !version) 354 | return 0; 355 | 356 | base = get_basename(file_name); 357 | 358 | switch (platform) { 359 | case BNCSUTIL_PLATFORM_X86: 360 | #ifdef MOS_WINDOWS 361 | infoSize = GetFileVersionInfoSize(file_name, &bytesRead); 362 | if (infoSize == 0) 363 | return 0; 364 | buf = (LPBYTE) VirtualAlloc(NULL, infoSize, MEM_COMMIT, 365 | PAGE_READWRITE); 366 | if (buf == NULL) 367 | return 0; 368 | if (GetFileVersionInfo(file_name, NULL, infoSize, buf) == FALSE) 369 | return 0; 370 | if (!VerQueryValue(buf, "\\", (LPVOID*) &ffi, (PUINT) &infoSize)) 371 | return 0; 372 | 373 | *version = 374 | ((HIWORD(ffi->dwProductVersionMS) & 0xFF) << 24) | 375 | ((LOWORD(ffi->dwProductVersionMS) & 0xFF) << 16) | 376 | ((HIWORD(ffi->dwProductVersionLS) & 0xFF) << 8) | 377 | (LOWORD(ffi->dwProductVersionLS) & 0xFF); 378 | #if DEBUG 379 | bncsutil_debug_message_a("%s version = %d.%d.%d.%d (0x%08X)", 380 | base, (HIWORD(ffi->dwProductVersionMS) & 0xFF), 381 | (LOWORD(ffi->dwProductVersionMS) & 0xFF), 382 | (HIWORD(ffi->dwProductVersionLS) & 0xFF), 383 | (LOWORD(ffi->dwProductVersionLS) & 0xFF), 384 | *version); 385 | #endif 386 | VirtualFree(buf, 0lu, MEM_RELEASE); 387 | #else 388 | pe = cm_pe_load(file_name); 389 | if (!pe) 390 | return 0; 391 | root = cm_pe_load_resources(pe); 392 | if (!root) { 393 | cm_pe_unload(pe); 394 | return 0; 395 | } 396 | 397 | for (i = 0; i < root->subdir_count; i++) { 398 | dir = (root->subdirs + i); 399 | if (dir->name == 16) { 400 | if (!cm_pe_fixed_version(pe, dir->subdirs->resources, 401 | &ffi)) 402 | { 403 | cm_pe_unload_resources(root); 404 | cm_pe_unload(pe); 405 | return 0; 406 | } 407 | break; 408 | } 409 | } 410 | *version = 411 | ((HIWORD(ffi.dwProductVersionMS) & 0xFF) << 24) | 412 | ((LOWORD(ffi.dwProductVersionMS) & 0xFF) << 16) | 413 | ((HIWORD(ffi.dwProductVersionLS) & 0xFF) << 8) | 414 | (LOWORD(ffi.dwProductVersionLS) & 0xFF); 415 | #if DEBUG 416 | bncsutil_debug_message_a("%s version = %d.%d.%d.%d (0x%08X)", 417 | base, (HIWORD(ffi.dwProductVersionMS) & 0xFF), 418 | (LOWORD(ffi.dwProductVersionMS) & 0xFF), 419 | (HIWORD(ffi.dwProductVersionLS) & 0xFF), 420 | (LOWORD(ffi.dwProductVersionLS) & 0xFF), 421 | *version); 422 | #endif 423 | 424 | cm_pe_unload_resources(root); 425 | cm_pe_unload(pe); 426 | #endif 427 | break; 428 | case BNCSUTIL_PLATFORM_MAC: 429 | case BNCSUTIL_PLATFORM_OSX: 430 | f = fopen(file_name, "r"); 431 | if (!f) 432 | return 0; 433 | if (fseek(f, -4, SEEK_END) != 0) { 434 | fclose(f); 435 | return 0; 436 | } 437 | if (fread(version, 4, 1, f) != 1) { 438 | fclose(f); 439 | return 0; 440 | } 441 | #ifdef MOS_WINDOWS 442 | fclose(f); 443 | #endif 444 | } 445 | 446 | #ifdef MOS_WINDOWS 447 | hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, 448 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 449 | if (hFile == INVALID_HANDLE_VALUE) 450 | return 0; 451 | file_size = GetFileSize(hFile, NULL); 452 | if (!GetFileTime(hFile, &ft, NULL, NULL)) { 453 | CloseHandle(hFile); 454 | return 0; 455 | } 456 | 457 | if (!FileTimeToSystemTime(&ft, &st)) { 458 | CloseHandle(hFile); 459 | return 0; 460 | } 461 | CloseHandle(hFile); 462 | 463 | ret = snprintf(exe_info, exe_info_size, 464 | "%s %02u/%02u/%02u %02u:%02u:%02u %lu", base, st.wMonth, 465 | st.wDay, (st.wYear % 100), st.wHour, st.wMinute, st.wSecond, 466 | file_size); 467 | 468 | #else 469 | if (!f) 470 | f = fopen(file_name, "r"); 471 | if (!f) 472 | return 0; 473 | if (fseek(f, 0, SEEK_END) == -1) { 474 | fclose(f); 475 | return 0; 476 | } 477 | file_size = ftell(f); 478 | fclose(f); 479 | 480 | if (stat(file_name, &st) != 0) 481 | return 0; 482 | 483 | time = gmtime(&st.st_mtime); 484 | if (!time) 485 | return 0; 486 | 487 | switch (platform) { 488 | case BNCSUTIL_PLATFORM_MAC: 489 | case BNCSUTIL_PLATFORM_OSX: 490 | if (time->tm_year >= 100) // y2k 491 | time->tm_year -= 100; 492 | break; 493 | } 494 | 495 | ret = (int) snprintf(exe_info, exe_info_size, 496 | "%s %02u/%02u/%02u %02u:%02u:%02u %lu", base, 497 | (time->tm_mon+1), time->tm_mday, (time->tm_year % 100), 498 | time->tm_hour, time->tm_min, time->tm_sec, file_size); 499 | #endif 500 | 501 | #if DEBUG 502 | bncsutil_debug_message(exe_info); 503 | #endif 504 | 505 | return ret; 506 | } 507 | 508 | #ifdef __cplusplus 509 | } // extern "C" 510 | #endif 511 | 512 | -------------------------------------------------------------------------------- /src/bncsutil/checkrevision.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * CheckRevision Interface 8 | * November 12, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef BNCSUTIL_CHECKREVISION_H 27 | #define BNCSUTIL_CHECKREVISION_H 28 | 29 | #ifdef __cplusplus 30 | 31 | #include 32 | 33 | extern "C" { 34 | #endif 35 | 36 | /** 37 | * Platform constants for getExeInfo(). 38 | */ 39 | #define BNCSUTIL_PLATFORM_X86 1 40 | #define BNCSUTIL_PLATFORM_WINDOWS 1 41 | #define BNCSUTIL_PLATFORM_WIN 1 42 | #define BNCSUTIL_PLATFORM_MAC 2 43 | #define BNCSUTIL_PLATFORM_PPC 2 44 | #define BNCSUTIL_PLATFORM_OSX 3 45 | 46 | /** 47 | * Reads an MPQ filename (e.g. IX86ver#.mpq), extracts the #, 48 | * and returns the int value of that number. Returns -1 on 49 | * failure. 50 | */ 51 | MEXP(int) extractMPQNumber(const char* mpqName); 52 | 53 | /** 54 | * Runs CheckRevision. 55 | * First file must be the executable file. 56 | */ 57 | MEXP(int) checkRevision( 58 | const char* valueString, 59 | const char* files[], 60 | int numFiles, 61 | int mpqNumber, 62 | unsigned long* checksum 63 | ); 64 | 65 | /** 66 | * Alternate form of CheckRevision function. 67 | * Really only useful for VB programmers; 68 | * VB seems to have trouble passing an array 69 | * of strings to a DLL function 70 | */ 71 | MEXP(int) checkRevisionFlat( 72 | const char* valueString, 73 | const char* file1, 74 | const char* file2, 75 | const char* file3, 76 | int mpqNumber, 77 | unsigned long* checksum 78 | ); 79 | 80 | /** 81 | * Retrieves version and date/size information from executable file. 82 | * Returns 0 on failure or length of exeInfoString. 83 | * If the generated string is longer than the buffer, the needed buffer 84 | * length will be returned, but the string will not be copied into 85 | * exeInfoString. Applications should check to see if the return value 86 | * is greater than the length of the buffer, and increase its size if 87 | * necessary. 88 | */ 89 | MEXP(int) getExeInfo(const char* file_name, 90 | char* exe_info, 91 | size_t exe_info_size, 92 | uint32_t* version, 93 | int platform); 94 | 95 | /** 96 | * Gets the seed value for the given MPQ file. If no seed value for the given 97 | * MPQ is registered with BNCSutil, returns 0. 98 | */ 99 | MEXP(long) get_mpq_seed(int mpq_number); 100 | 101 | /** 102 | * Sets the seed value for the given MPQ file. Returns the old seed value if 103 | * there was any, or 0 if this was a new addition. 104 | */ 105 | MEXP(long) set_mpq_seed(int mpq_number, long new_seed); 106 | 107 | #ifdef __cplusplus 108 | } // extern "C" 109 | #endif 110 | 111 | #endif /* BNCSUTIL_CHECKREVISION_H */ 112 | -------------------------------------------------------------------------------- /src/bncsutil/decodekey.cpp: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * BNCSutil 4 | * Battle.Net Utility Library 5 | * 6 | * Copyright (C) 2004-2006 Eric Naeseth 7 | * 8 | * CD-Key Decoder C Wrappers 9 | * October 17, 2004 10 | * 11 | * This library is free software; you can redistribute it and/or 12 | * modify it under the terms of the GNU Lesser General Public 13 | * License as published by the Free Software Foundation; either 14 | * version 2.1 of the License, or (at your option) any later version. 15 | * 16 | * This library is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | * Lesser General Public License for more details. 20 | * 21 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 22 | * distribution in the file COPYING. If you did not receive this copy, 23 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 24 | * Boston, MA 02111-1307 USA 25 | */ 26 | 27 | #ifndef DECODECDKEY_CPP 28 | #define DECODECDKEY_CPP 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef MOS_WINDOWS 35 | #include 36 | #else 37 | #include 38 | #include 39 | #endif 40 | #include 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | #define DEFAULT_DECODERS_SIZE 4 47 | #define MUTEX_TIMEOUT_MS 6000L 48 | 49 | #ifndef CLOCKS_PER_SEC 50 | # ifdef CLK_TCK 51 | # define CLOCKS_PER_SEC CLK_TCK 52 | # else 53 | # define CLOCKS_PER_SEC 1000000 54 | # endif 55 | #endif 56 | 57 | CDKeyDecoder** decoders; 58 | unsigned int numDecoders = 0; 59 | unsigned int sizeDecoders = 0; 60 | 61 | #ifdef MOS_WINDOWS 62 | // HANDLE mutex; 63 | CRITICAL_SECTION kd_control; 64 | #else 65 | pthread_mutex_t mutex; 66 | #endif 67 | 68 | int kd_lock_decoders() { 69 | #ifdef MOS_WINDOWS 70 | /* DWORD dwWaitResult; 71 | dwWaitResult = WaitForSingleObject(mutex, MUTEX_TIMEOUT_MS); 72 | switch (dwWaitResult) { 73 | case WAIT_OBJECT_0: 74 | // success 75 | break; 76 | case WAIT_TIMEOUT: 77 | return 0; 78 | break; 79 | case WAIT_ABANDONED: 80 | // weird, but should be OK 81 | break; 82 | default: 83 | return 0; 84 | break; 85 | }*/ 86 | EnterCriticalSection(&kd_control); 87 | #else 88 | int err = 0; 89 | pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 90 | struct timespec wait_time = {0, MUTEX_TIMEOUT_MS * 1000}; 91 | 92 | err = pthread_cond_timedwait(&cond, &mutex, &wait_time); 93 | switch (err) { 94 | case 0: 95 | // success 96 | break; 97 | default: 98 | // error 99 | return 0; 100 | } 101 | #endif 102 | return 1; 103 | } 104 | 105 | #ifdef MOS_WINDOWS 106 | #define kd_unlock_decoders() LeaveCriticalSection(&kd_control) 107 | #else 108 | #define kd_unlock_decoders() pthread_mutex_unlock(&mutex) 109 | #endif 110 | 111 | MEXP(int) kd_quick(const char* cd_key, uint32_t client_token, 112 | uint32_t server_token, uint32_t* public_value, 113 | uint32_t* product, char* hash_buffer, size_t buffer_len) 114 | { 115 | CDKeyDecoder kd(cd_key, strlen(cd_key)); 116 | size_t hash_len; 117 | 118 | if (kd.isKeyValid() == 0) 119 | return 0; 120 | 121 | *public_value = kd.getVal1(); 122 | *product = kd.getProduct(); 123 | 124 | hash_len = kd.calculateHash(client_token, server_token); 125 | if ((hash_len == 0U) || hash_len > buffer_len) 126 | return 0; 127 | 128 | kd.getHash(hash_buffer); 129 | return 1; 130 | } 131 | 132 | MEXP(int) kd_init() { 133 | static int has_run = 0; 134 | 135 | if (has_run) 136 | return 1; 137 | 138 | #ifdef MOS_WINDOWS 139 | /*mutex = CreateMutex(NULL, FALSE, NULL); 140 | if (mutex == NULL) 141 | return 0;*/ 142 | InitializeCriticalSection(&kd_control); 143 | #else 144 | if (pthread_mutex_init(&mutex, NULL) != 0) 145 | return 0; 146 | #endif 147 | numDecoders = 0; 148 | sizeDecoders = 0; 149 | decoders = (CDKeyDecoder**) 0; 150 | has_run = 1; 151 | 152 | #if DEBUG 153 | bncsutil_debug_message("Initialized key decoding C API."); 154 | #endif 155 | 156 | return 1; 157 | } 158 | 159 | unsigned int kd_findAvailable() { 160 | unsigned int i; 161 | CDKeyDecoder** d; 162 | 163 | d = decoders; 164 | for (i = 0; i < sizeDecoders; i++) { 165 | if (*d == (CDKeyDecoder*) 0) 166 | return i; 167 | d++; 168 | } 169 | 170 | // no room available, must expand 171 | decoders = (CDKeyDecoder**) realloc(decoders, sizeof(CDKeyDecoder*) * 172 | (sizeDecoders + DEFAULT_DECODERS_SIZE)); 173 | if (!decoders) 174 | return (unsigned int) -1; 175 | 176 | memset(decoders + sizeDecoders, 0, 177 | sizeof(CDKeyDecoder*) * DEFAULT_DECODERS_SIZE); // zero new memory 178 | 179 | i = sizeDecoders; 180 | sizeDecoders += DEFAULT_DECODERS_SIZE; 181 | return i; 182 | } 183 | 184 | MEXP(int) kd_create(const char* cdkey, const int keyLength) { 185 | unsigned int i; 186 | CDKeyDecoder** d; 187 | static int dcs_initialized = 0; 188 | 189 | if (dcs_initialized == 0) { 190 | if (kd_init() == 0) 191 | return -1; 192 | dcs_initialized = 1; 193 | } 194 | 195 | if (kd_lock_decoders() == 0) return -1; 196 | 197 | i = kd_findAvailable(); 198 | if (i == (unsigned int) -1) 199 | return -1; 200 | 201 | d = (decoders + i); 202 | *d = new CDKeyDecoder(cdkey, keyLength); 203 | if (!(**d).isKeyValid()) { 204 | delete *d; 205 | *d = (CDKeyDecoder*) 0; 206 | return -1; 207 | } 208 | 209 | numDecoders++; 210 | 211 | kd_unlock_decoders(); 212 | return (int) i; 213 | } 214 | 215 | /* 216 | MEXP(int) kd_create(char* cdkey, int keyLength) { 217 | if (!kd_lock_decoders()) return -1; 218 | CDKeyDecoder* d; 219 | unsigned int i; 220 | if (numDecoders >= sizeDecoders) { 221 | CDKeyDecoder** temp = new CDKeyDecoder*[sizeDecoders]; 222 | for (unsigned int j = 0; j < sizeDecoders; j++) { 223 | temp[j] = decoders[j]; 224 | } 225 | delete [] decoders; 226 | decoders = new CDKeyDecoder*[sizeDecoders + DEFAULT_DECODERS_SIZE]; 227 | 228 | for (unsigned int j = 0; j < sizeDecoders; j++) { 229 | decoders[j] = temp[j]; 230 | } 231 | delete [] temp; 232 | sizeDecoders += DEFAULT_DECODERS_SIZE; 233 | } 234 | i = numDecoders++; 235 | decoders[i] = new CDKeyDecoder(cdkey, keyLength); 236 | d = decoders[i]; 237 | if (!d->isKeyValid()) { 238 | delete decoders[i]; 239 | return -1; 240 | } 241 | kd_unlock_decoders(); 242 | 243 | d = NULL; 244 | return (int) i; 245 | }*/ 246 | 247 | MEXP(int) kd_free(const int decoder) { 248 | CDKeyDecoder* d; 249 | 250 | if (kd_lock_decoders() == 0) return 0; 251 | 252 | if ((unsigned int) decoder >= sizeDecoders) 253 | return 0; 254 | 255 | d = *(decoders + decoder); 256 | if (!d) 257 | return 0; 258 | 259 | delete d; 260 | *(decoders + decoder) = (CDKeyDecoder*) 0; 261 | 262 | kd_unlock_decoders(); 263 | return 1; 264 | } 265 | 266 | MEXP(int) kd_val2Length(int decoder) { 267 | CDKeyDecoder* d; 268 | int value; 269 | 270 | if (kd_lock_decoders() == 0) return -1; 271 | 272 | if ((unsigned int) decoder >= sizeDecoders) 273 | return -1; 274 | 275 | d = *(decoders + decoder); 276 | if (!d) 277 | return -1; 278 | 279 | value = d->getVal2Length(); 280 | 281 | kd_unlock_decoders(); 282 | return value; 283 | } 284 | 285 | MEXP(int) kd_product(int decoder) { 286 | CDKeyDecoder* d; 287 | int value; 288 | 289 | if (kd_lock_decoders() == 0) return -1; 290 | 291 | if ((unsigned int) decoder >= sizeDecoders) 292 | return -1; 293 | 294 | d = *(decoders + decoder); 295 | if (!d) 296 | return -1; 297 | 298 | value = d->getProduct(); 299 | 300 | kd_unlock_decoders(); 301 | return value; 302 | } 303 | 304 | MEXP(int) kd_val1(const int decoder) { 305 | CDKeyDecoder* d; 306 | int value; 307 | 308 | if (kd_lock_decoders() == 0) return -1; 309 | 310 | if ((unsigned int) decoder >= sizeDecoders) 311 | return -1; 312 | 313 | d = *(decoders + decoder); 314 | if (!d) 315 | return -1; 316 | 317 | value = d->getVal1(); 318 | 319 | kd_unlock_decoders(); 320 | return value; 321 | } 322 | 323 | MEXP(int) kd_val2(int decoder) { 324 | CDKeyDecoder* d; 325 | int value; 326 | 327 | if (kd_lock_decoders() == 0) return -1; 328 | 329 | if ((unsigned int) decoder >= sizeDecoders) 330 | return -1; 331 | 332 | d = *(decoders + decoder); 333 | if (!d) 334 | return -1; 335 | 336 | value = d->getVal2(); 337 | 338 | kd_unlock_decoders(); 339 | return value; 340 | } 341 | 342 | MEXP(int) kd_longVal2(const int decoder, char* out) { 343 | CDKeyDecoder* d; 344 | int value; 345 | 346 | if (kd_lock_decoders() == 0) return -1; 347 | 348 | if ((unsigned int) decoder >= sizeDecoders) 349 | return -1; 350 | 351 | d = *(decoders + decoder); 352 | if (!d) 353 | return -1; 354 | 355 | value = d->getLongVal2(out); 356 | 357 | kd_unlock_decoders(); 358 | return value; 359 | } 360 | 361 | MEXP(int) kd_calculateHash(const int decoder, const uint32_t clientToken, 362 | const uint32_t serverToken) 363 | { 364 | CDKeyDecoder* d; 365 | int value; 366 | 367 | if (kd_lock_decoders() == 0) return -1; 368 | 369 | if ((unsigned int) decoder >= sizeDecoders) 370 | return -1; 371 | 372 | d = *(decoders + decoder); 373 | if (!d) 374 | return -1; 375 | 376 | value = (int) d->calculateHash(clientToken, serverToken); 377 | 378 | kd_unlock_decoders(); 379 | return value; 380 | } 381 | 382 | MEXP(int) kd_getHash(const int decoder, char* out) { 383 | CDKeyDecoder* d; 384 | int value; 385 | 386 | if (kd_lock_decoders() == 0) return -1; 387 | 388 | if ((unsigned int) decoder >= sizeDecoders) 389 | return -1; 390 | 391 | d = *(decoders + decoder); 392 | if (!d) 393 | return -1; 394 | 395 | value = (int) d->getHash(out); 396 | 397 | kd_unlock_decoders(); 398 | return value; 399 | } 400 | 401 | MEXP(int) kd_isValid(const int decoder) { 402 | CDKeyDecoder* d; 403 | int value; 404 | 405 | if (kd_lock_decoders() == 0) return -1; 406 | 407 | if ((unsigned int) decoder >= sizeDecoders) 408 | return -1; 409 | 410 | d = *(decoders + decoder); 411 | if (!d) 412 | return -1; 413 | 414 | value = d->isKeyValid(); 415 | 416 | kd_unlock_decoders(); 417 | return value; 418 | } 419 | 420 | #ifdef __cplusplus 421 | } 422 | #endif 423 | 424 | #endif /* DECODECDKEY_CPP -- note to self: why is this here? */ 425 | -------------------------------------------------------------------------------- /src/bncsutil/decodekey.h: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * BNCSutil 4 | * Battle.Net Utility Library 5 | * 6 | * Copyright (C) 2004-2006 Eric Naeseth 7 | * 8 | * CD-Key Decoder C Wrappers 9 | * October 17, 2004 10 | * 11 | * This library is free software; you can redistribute it and/or 12 | * modify it under the terms of the GNU Lesser General Public 13 | * License as published by the Free Software Foundation; either 14 | * version 2.1 of the License, or (at your option) any later version. 15 | * 16 | * This library is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | * Lesser General Public License for more details. 20 | * 21 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 22 | * distribution in the file COPYING. If you did not receive this copy, 23 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 24 | * Boston, MA 02111-1307 USA 25 | */ 26 | 27 | #ifndef DECODEKEY_H 28 | #define DECODEKEY_H 29 | 30 | #include 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /** 37 | * Decodes a CD-key, retrieves its relevant values, and calculates a hash 38 | * suitable for SID_AUTH_CHECK (0x51) in one function call. Returns 1 on 39 | * success or 0 on failure. A call to kd_init does NOT need to be made before 40 | * calling this function. Available since BNCSutil 1.1.0. 41 | */ 42 | MEXP(int) kd_quick(const char* cd_key, uint32_t client_token, 43 | uint32_t server_token, uint32_t* public_value, 44 | uint32_t* product, char* hash_buffer, size_t buffer_len); 45 | 46 | /** 47 | * Initializes the CD-key decoding C wrappers. 48 | * Returns 1 on success or 0 on failure. 49 | */ 50 | MEXP(int) kd_init(); 51 | 52 | /** 53 | * Creates a new CD-key decoder. Returns its ID on success 54 | * or -1 on failure or invalid CD-key. 55 | */ 56 | MEXP(int) kd_create(const char* cdkey, int keyLength); 57 | 58 | /** 59 | * Frees the specified CD-key decoder. 60 | * Returns 1 on success or 0 on failure. 61 | */ 62 | MEXP(int) kd_free(int decoder); 63 | 64 | /** 65 | * Gets the length of the private value for the given decoder. 66 | * Returns the length or 0 on failure. 67 | */ 68 | MEXP(int) kd_val2Length(int decoder); 69 | 70 | /** 71 | * Gets the product value for the given decoder. 72 | * Returns the length or 0 on failure. 73 | */ 74 | MEXP(int) kd_product(int decoder); 75 | 76 | /** 77 | * Gets the public value for the given decoder. 78 | * Returns the length or 0 on failure. 79 | */ 80 | MEXP(int) kd_val1(int decoder); 81 | 82 | /** 83 | * Gets the rivate value for the given decoder. 84 | * Only use this function if kd_val2Length <= 4. 85 | * Returns the length or 0 on failure. 86 | */ 87 | MEXP(int) kd_val2(int decoder); 88 | 89 | /** 90 | * Gets the length of the private value for the given decoder. 91 | * Only use this function if kd_val2Length > 4. 92 | * Returns the length or 0 on failure. 93 | */ 94 | MEXP(int) kd_longVal2(int decoder, char* out); 95 | 96 | /** 97 | * Calculates the hash of the key values for SID_AUTH_CHECK (0x51). 98 | * Returns the hash length or 0 on failure. 99 | */ 100 | MEXP(int) kd_calculateHash(int decoder, uint32_t clientToken, 101 | uint32_t serverToken); 102 | 103 | /** 104 | * Places the key hash in "out". The "out" buffer must be 105 | * at least the length returned from kd_calculateHash. 106 | * Returns the hash length or 0 on failure. 107 | */ 108 | MEXP(int) kd_getHash(int decoder, char* out); 109 | 110 | /** 111 | * [!] kd_isValid has been deprecated. kd_create checks 112 | * whether the key was valid before returning, and 113 | * destroys the decoder and returns an error code 114 | * if it was invalid. 115 | */ 116 | MEXP(int) kd_isValid(int decoder); 117 | 118 | #ifdef __cplusplus 119 | } // extern "C" 120 | #endif 121 | 122 | #endif // DECODEKEY_H 123 | -------------------------------------------------------------------------------- /src/bncsutil/file.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef MOS_WINDOWS 7 | #define WIN32_LEAN_AND_MEAN 8 | #define BWIN 1 9 | #include 10 | 11 | typedef std::map mapping_map; 12 | #else 13 | #define BWIN 0 14 | #include 15 | #include 16 | #include 17 | 18 | typedef std::map mapping_map; 19 | #endif 20 | 21 | struct _file 22 | { 23 | #if BWIN 24 | HANDLE f; 25 | #else 26 | FILE* f; 27 | #endif 28 | const char* filename; 29 | mapping_map mappings; 30 | }; 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #if BWIN 37 | 38 | file_t file_open(const char* filename, unsigned int mode) 39 | { 40 | file_t data; 41 | HANDLE file; 42 | DWORD access; 43 | DWORD share_mode; 44 | DWORD open_mode; 45 | //const char* sys_err; 46 | size_t filename_buf_len; 47 | 48 | if (mode & FILE_READ) { 49 | access = GENERIC_READ; 50 | share_mode = FILE_SHARE_READ; 51 | open_mode = OPEN_EXISTING; 52 | } else if (mode & FILE_WRITE) { 53 | access = GENERIC_WRITE; 54 | share_mode = 0; 55 | open_mode = CREATE_ALWAYS; 56 | } 57 | 58 | file = CreateFile(filename, access, share_mode, NULL, open_mode, 59 | FILE_ATTRIBUTE_NORMAL, NULL); 60 | 61 | if (file == INVALID_HANDLE_VALUE) { 62 | //sys_err = sys_error_msg(); 63 | //bncsutil_debug_message_a("Cannot open file \"%s\"; %s", filename, sys_err); 64 | //free_sys_err_msg(sys_err); 65 | return ((file_t) 0); 66 | } 67 | 68 | try { 69 | data = new _file; 70 | } catch (std::bad_alloc) { 71 | //bncsutil_debug_message_a("Failed to allocate %u bytes to hold file structure.", sizeof(struct _file)); 72 | CloseHandle(file); 73 | return (file_t) 0; 74 | } 75 | 76 | filename_buf_len = strlen(filename) + 1; 77 | data->filename = (const char*) malloc(filename_buf_len); 78 | if (!data->filename) { 79 | //bncsutil_debug_message_a("Failed to allocate %u bytes to hold filename.", filename_buf_len); 80 | CloseHandle(file); 81 | delete data; 82 | return (file_t) 0; 83 | } 84 | strcpy_s((char*) data->filename, filename_buf_len, filename); 85 | 86 | data->f = file; 87 | 88 | return data; 89 | } 90 | 91 | void file_close(file_t file) 92 | { 93 | mapping_map::iterator it; 94 | 95 | if (!file) { 96 | //bncsutil_debug_message_a("error: null pointer given to file_close"); 97 | return; 98 | } 99 | 100 | for (it = file->mappings.begin(); it != file->mappings.end(); it++) { 101 | UnmapViewOfFile((*it).first); 102 | CloseHandle((*it).second); 103 | } 104 | 105 | CloseHandle((HANDLE) file->f); 106 | free((void*) file->filename); 107 | delete file; 108 | } 109 | 110 | size_t file_read(file_t file, void* ptr, size_t size, size_t count) 111 | { 112 | DWORD bytes_read; 113 | 114 | if (!ReadFile(file->f, ptr, (DWORD) (size * count), &bytes_read, NULL)) { 115 | return (size_t) 0; 116 | } 117 | 118 | return (size_t) bytes_read; 119 | } 120 | 121 | size_t file_write(file_t file, const void* ptr, size_t size, 122 | size_t count) 123 | { 124 | DWORD bytes_written; 125 | 126 | if (!WriteFile(file->f, ptr, (DWORD) (size * count), &bytes_written, NULL)) 127 | return (size_t) 0; 128 | 129 | return (size_t) bytes_written; 130 | } 131 | 132 | size_t file_size(file_t file) 133 | { 134 | return (size_t) GetFileSize(file->f, (LPDWORD) 0); 135 | } 136 | 137 | void* file_map(file_t file, size_t len, off_t offset) 138 | { 139 | HANDLE mapping = 140 | CreateFileMapping((HANDLE) file->f, NULL, PAGE_READONLY, 0, 0, NULL); 141 | void* base; 142 | //const char* err; 143 | 144 | if (!mapping) { 145 | //err = sys_error_msg(); 146 | //bncsutil_debug_message_a("Failed to create file mapping for \"%s\": %s", file->filename, err); 147 | //free_sys_err_msg(err); 148 | return (void*) 0; 149 | } 150 | 151 | base = MapViewOfFile(mapping, FILE_MAP_READ, 0, (DWORD) offset, len); 152 | if (!base) { 153 | CloseHandle(mapping); 154 | //err = sys_error_msg(); 155 | //bncsutil_debug_message_a("Failed to map %u bytes of \"%s\" starting at %u: %s", len, file->filename, offset, err); 156 | //free_sys_err_msg(err); 157 | return (void*) 0; 158 | } 159 | 160 | file->mappings[base] = mapping; 161 | 162 | return base; 163 | } 164 | 165 | void file_unmap(file_t file, const void* base) 166 | { 167 | mapping_map::iterator item = file->mappings.find(base); 168 | HANDLE mapping; 169 | 170 | if (item == file->mappings.end()) { 171 | //bncsutil_debug_message_a("warning: failed to unmap the block starting at %p from %s; unknown block.", base, file->filename); 172 | return; 173 | } 174 | 175 | mapping = (*item).second; 176 | 177 | UnmapViewOfFile(base); 178 | CloseHandle(mapping); 179 | 180 | file->mappings.erase(item); 181 | } 182 | 183 | #else 184 | 185 | file_t file_open(const char* filename, const unsigned int mode_flags) 186 | { 187 | char mode[] = "rb"; 188 | file_t data; 189 | FILE* f; 190 | size_t filename_buf_len; 191 | //const char* err; 192 | 193 | if (mode_flags & FILE_WRITE) 194 | mode[0] = 'w'; 195 | 196 | f = fopen(filename, mode); 197 | if (!f) { 198 | return (file_t) 0; 199 | } 200 | 201 | try { 202 | data = new _file; 203 | } catch (std::bad_alloc) { 204 | //bncsutil_debug_message_a("Failed to allocate %u bytes to hold file structure.", sizeof(struct _file)); 205 | fclose(f); 206 | return (file_t) 0; 207 | } 208 | 209 | filename_buf_len = strlen(filename) + 1; 210 | data->filename = (const char*) malloc(filename_buf_len); 211 | if (!data->filename) { 212 | //err = sys_error_msg(); 213 | //bncsutil_debug_message_a("Failed to allocate %u bytes to hold filename; %s", filename_buf_len); 214 | //free_sys_err_msg(err); 215 | fclose(f); 216 | delete data; 217 | return (file_t) 0; 218 | } 219 | strcpy((char*) data->filename, filename); 220 | 221 | data->f = f; 222 | 223 | return data; 224 | } 225 | 226 | void file_close(file_t file) 227 | { 228 | mapping_map::iterator it; 229 | 230 | if (!file) { 231 | //bncsutil_debug_message("error: null pointer given to file_close"); 232 | return; 233 | } 234 | 235 | for (it = file->mappings.begin(); it != file->mappings.end(); it++) { 236 | munmap((void*) (*it).first, (*it).second); 237 | } 238 | 239 | fclose(file->f); 240 | delete file; 241 | } 242 | 243 | size_t file_read(file_t file, void* ptr, size_t size, size_t count) 244 | { 245 | return fread(ptr, size, count, file->f); 246 | } 247 | 248 | size_t file_write(file_t file, const void* ptr, size_t size, 249 | size_t count) 250 | { 251 | return fwrite(ptr, size, count, file->f); 252 | } 253 | 254 | size_t file_size(file_t file) 255 | { 256 | long cur_pos = ftell(file->f); 257 | size_t size_of_file; 258 | 259 | fseek(file->f, 0, SEEK_END); 260 | size_of_file = (size_t) ftell(file->f); 261 | fseek(file->f, cur_pos, SEEK_SET); 262 | 263 | return size_of_file; 264 | } 265 | 266 | void* file_map(file_t file, const size_t len, const off_t offset) 267 | { 268 | const int fd = fileno(file->f); 269 | void* base = mmap((void*) 0, len, PROT_READ, MAP_SHARED, fd, offset); 270 | //const char* err; 271 | 272 | if (!base) { 273 | //err = sys_error_msg(); 274 | //bncsutil_debug_message_a("error: failed to map %u bytes of %s starting at %u into memory; %s", len, file->filename, offset, err); 275 | //free_sys_err_msg(err); 276 | return (void*) 0; 277 | } 278 | 279 | file->mappings[base] = len; 280 | 281 | return base; 282 | } 283 | 284 | void file_unmap(file_t file, const void* mapping) 285 | { 286 | mapping_map::iterator item = file->mappings.find(mapping); 287 | size_t len; 288 | 289 | if (item == file->mappings.end()) { 290 | //bncsutil_debug_message_a("warning: failed to unmap the block starting at %p from %s; unknown block.", base, file->filename); 291 | return; 292 | } 293 | 294 | len = (*item).second; 295 | 296 | munmap((void*) mapping, len); 297 | 298 | file->mappings.erase(item); 299 | } 300 | 301 | #endif 302 | 303 | #ifdef __cplusplus 304 | } 305 | #endif 306 | -------------------------------------------------------------------------------- /src/bncsutil/file.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * File Access 8 | * February 12, 2006 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef _FILE_H_INCLUDED_ 27 | #define _FILE_H_INCLUDED_ 1 28 | 29 | #ifdef MOS_WINDOWS 30 | typedef long off_t; 31 | #else 32 | #include 33 | #endif 34 | 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | typedef struct _file* file_t; 41 | 42 | #define FILE_READ (0x01) 43 | #define FILE_WRITE (0x02) 44 | 45 | 46 | file_t file_open(const char* filename, unsigned int mode_flags); 47 | void file_close(file_t file); 48 | size_t file_read(file_t file, void* ptr, size_t size, size_t count); 49 | size_t file_write(file_t file, const void* ptr, size_t size, 50 | size_t count); 51 | size_t file_size(file_t file); 52 | 53 | void* file_map(file_t file, size_t len, off_t offset); 54 | void file_unmap(file_t file, const void* mapping); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* _FILE_H_INCLUDED_ */ 61 | -------------------------------------------------------------------------------- /src/bncsutil/keytables.h: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * BNCSutil 4 | * Battle.Net Utility Library 5 | * 6 | * Copyright (C) 2004-2006 Eric Naeseth 7 | * 8 | * WarCraft II/Diablo II and WarCraft III Decoding Tables 9 | * October 2, 2004 10 | * 11 | * This library is free software; you can redistribute it and/or 12 | * modify it under the terms of the GNU Lesser General Public 13 | * License as published by the Free Software Foundation; either 14 | * version 2.1 of the License, or (at your option) any later version. 15 | * 16 | * This library is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | * Lesser General Public License for more details. 20 | * 21 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 22 | * distribution in the file COPYING. If you did not receive this copy, 23 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 24 | * Boston, MA 02111-1307 USA 25 | */ 26 | 27 | #ifndef BNCSUTIL_KEYTABLES_H 28 | #define BNCSUTIL_KEYTABLES_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | const unsigned char w2Map[] = { 35 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 36 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 37 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 38 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 39 | 0xFF, 0xFF, 0x00, 0xFF, 0x01, 0xFF, 0x02, 0x03, 0x04, 0x05, 0xFF, 0xFF, 40 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 41 | 0x0C, 0xFF, 0x0D, 0x0E, 0xFF, 0x0F, 0x10, 0xFF, 0x11, 0xFF, 0x12, 0xFF, 42 | 0x13, 0xFF, 0x14, 0x15, 0x16, 0xFF, 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 43 | 0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0xFF, 0x0D, 0x0E, 44 | 0xFF, 0x0F, 0x10, 0xFF, 0x11, 0xFF, 0x12, 0xFF, 0x13, 0xFF, 0x14, 0x15, 45 | 0x16, 0xFF, 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 46 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 47 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 48 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 49 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 50 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 51 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 52 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 53 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 54 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 55 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 56 | 0xFF, 0xFF, 0xFF, 0xFF 57 | }; 58 | 59 | const unsigned char w3KeyMap[] = { 60 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 61 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 62 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 63 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 64 | 0xFF, 0xFF, 0x00, 0xFF, 0x01, 0xFF, 0x02, 0x03, 0x04, 0x05, 0xFF, 65 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 66 | 0x0B, 0x0C, 0xFF, 0x0D, 0x0E, 0xFF, 0x0F, 0x10, 0xFF, 0x11, 0xFF, 0x12, 67 | 0xFF, 0x13, 0xFF, 0x14, 0x15, 0x16, 0x17, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 68 | 0xFF, 0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0xFF, 0x0D, 69 | 0x0E, 0xFF, 0x0F, 0x10, 0xFF, 0x11, 0xFF, 0x12, 0xFF, 0x13, 0xFF, 0x14, 70 | 0x15, 0x16, 0x17, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 71 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 72 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 73 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 74 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 75 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 76 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 77 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 78 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 79 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 80 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 81 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 82 | }; 83 | 84 | const unsigned char w3TranslateMap[] = { 85 | 0x09, 0x04, 0x07, 0x0F, 0x0D, 0x0A, 0x03, 0x0B, 0x01, 0x02, 0x0C, 0x08, 86 | 0x06, 0x0E, 0x05, 0x00, 0x09, 0x0B, 0x05, 0x04, 0x08, 0x0F, 0x01, 0x0E, 87 | 0x07, 0x00, 0x03, 0x02, 0x0A, 0x06, 0x0D, 0x0C, 0x0C, 0x0E, 0x01, 0x04, 88 | 0x09, 0x0F, 0x0A, 0x0B, 0x0D, 0x06, 0x00, 0x08, 0x07, 0x02, 0x05, 0x03, 89 | 0x0B, 0x02, 0x05, 0x0E, 0x0D, 0x03, 0x09, 0x00, 0x01, 0x0F, 0x07, 0x0C, 90 | 0x0A, 0x06, 0x04, 0x08, 0x06, 0x02, 0x04, 0x05, 0x0B, 0x08, 0x0C, 0x0E, 91 | 0x0D, 0x0F, 0x07, 0x01, 0x0A, 0x00, 0x03, 0x09, 0x05, 0x04, 0x0E, 0x0C, 92 | 0x07, 0x06, 0x0D, 0x0A, 0x0F, 0x02, 0x09, 0x01, 0x00, 0x0B, 0x08, 0x03, 93 | 0x0C, 0x07, 0x08, 0x0F, 0x0B, 0x00, 0x05, 0x09, 0x0D, 0x0A, 0x06, 0x0E, 94 | 0x02, 0x04, 0x03, 0x01, 0x03, 0x0A, 0x0E, 0x08, 0x01, 0x0B, 0x05, 0x04, 95 | 0x02, 0x0F, 0x0D, 0x0C, 0x06, 0x07, 0x09, 0x00, 0x0C, 0x0D, 0x01, 0x0F, 96 | 0x08, 0x0E, 0x05, 0x0B, 0x03, 0x0A, 0x09, 0x00, 0x07, 0x02, 0x04, 0x06, 97 | 0x0D, 0x0A, 0x07, 0x0E, 0x01, 0x06, 0x0B, 0x08, 0x0F, 0x0C, 0x05, 0x02, 98 | 0x03, 0x00, 0x04, 0x09, 0x03, 0x0E, 0x07, 0x05, 0x0B, 0x0F, 0x08, 0x0C, 99 | 0x01, 0x0A, 0x04, 0x0D, 0x00, 0x06, 0x09, 0x02, 0x0B, 0x06, 0x09, 0x04, 100 | 0x01, 0x08, 0x0A, 0x0D, 0x07, 0x0E, 0x00, 0x0C, 0x0F, 0x02, 0x03, 0x05, 101 | 0x0C, 0x07, 0x08, 0x0D, 0x03, 0x0B, 0x00, 0x0E, 0x06, 0x0F, 0x09, 0x04, 102 | 0x0A, 0x01, 0x05, 0x02, 0x0C, 0x06, 0x0D, 0x09, 0x0B, 0x00, 0x01, 0x02, 103 | 0x0F, 0x07, 0x03, 0x04, 0x0A, 0x0E, 0x08, 0x05, 0x03, 0x06, 0x01, 0x05, 104 | 0x0B, 0x0C, 0x08, 0x00, 0x0F, 0x0E, 0x09, 0x04, 0x07, 0x0A, 0x0D, 0x02, 105 | 0x0A, 0x07, 0x0B, 0x0F, 0x02, 0x08, 0x00, 0x0D, 0x0E, 0x0C, 0x01, 0x06, 106 | 0x09, 0x03, 0x05, 0x04, 0x0A, 0x0B, 0x0D, 0x04, 0x03, 0x08, 0x05, 0x09, 107 | 0x01, 0x00, 0x0F, 0x0C, 0x07, 0x0E, 0x02, 0x06, 0x0B, 0x04, 0x0D, 0x0F, 108 | 0x01, 0x06, 0x03, 0x0E, 0x07, 0x0A, 0x0C, 0x08, 0x09, 0x02, 0x05, 0x00, 109 | 0x09, 0x06, 0x07, 0x00, 0x01, 0x0A, 0x0D, 0x02, 0x03, 0x0E, 0x0F, 0x0C, 110 | 0x05, 0x0B, 0x04, 0x08, 0x0D, 0x0E, 0x05, 0x06, 0x01, 0x09, 0x08, 0x0C, 111 | 0x02, 0x0F, 0x03, 0x07, 0x0B, 0x04, 0x00, 0x0A, 0x09, 0x0F, 0x04, 0x00, 112 | 0x01, 0x06, 0x0A, 0x0E, 0x02, 0x03, 0x07, 0x0D, 0x05, 0x0B, 0x08, 0x0C, 113 | 0x03, 0x0E, 0x01, 0x0A, 0x02, 0x0C, 0x08, 0x04, 0x0B, 0x07, 0x0D, 0x00, 114 | 0x0F, 0x06, 0x09, 0x05, 0x07, 0x02, 0x0C, 0x06, 0x0A, 0x08, 0x0B, 0x00, 115 | 0x0F, 0x04, 0x03, 0x0E, 0x09, 0x01, 0x0D, 0x05, 0x0C, 0x04, 0x05, 0x09, 116 | 0x0A, 0x02, 0x08, 0x0D, 0x03, 0x0F, 0x01, 0x0E, 0x06, 0x07, 0x0B, 0x00, 117 | 0x0A, 0x08, 0x0E, 0x0D, 0x09, 0x0F, 0x03, 0x00, 0x04, 0x06, 0x01, 0x0C, 118 | 0x07, 0x0B, 0x02, 0x05, 0x03, 0x0C, 0x04, 0x0A, 0x02, 0x0F, 0x0D, 0x0E, 119 | 0x07, 0x00, 0x05, 0x08, 0x01, 0x06, 0x0B, 0x09, 0x0A, 0x0C, 0x01, 0x00, 120 | 0x09, 0x0E, 0x0D, 0x0B, 0x03, 0x07, 0x0F, 0x08, 0x05, 0x02, 0x04, 0x06, 121 | 0x0E, 0x0A, 0x01, 0x08, 0x07, 0x06, 0x05, 0x0C, 0x02, 0x0F, 0x00, 0x0D, 122 | 0x03, 0x0B, 0x04, 0x09, 0x03, 0x08, 0x0E, 0x00, 0x07, 0x09, 0x0F, 0x0C, 123 | 0x01, 0x06, 0x0D, 0x02, 0x05, 0x0A, 0x0B, 0x04, 0x03, 0x0A, 0x0C, 0x04, 124 | 0x0D, 0x0B, 0x09, 0x0E, 0x0F, 0x06, 0x01, 0x07, 0x02, 0x00, 0x05, 0x08 125 | }; 126 | 127 | #ifdef __cplusplus 128 | } // extern "C" 129 | #endif 130 | 131 | #endif /* BNCSUTIL_KEYTABLES_H */ 132 | -------------------------------------------------------------------------------- /src/bncsutil/libinfo.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Library Information 8 | * November 16, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | MEXP(unsigned long) bncsutil_getVersion() { 31 | return BNCSUTIL_VERSION; 32 | } 33 | 34 | MEXP(int) bncsutil_getVersionString(char* outBuf) { 35 | unsigned long major, minor, rev, ver; 36 | int printed; 37 | ver = BNCSUTIL_VERSION; 38 | // major 39 | major = (unsigned long) (BNCSUTIL_VERSION / 10000); 40 | if (major > 99 || major < 0) return 0; 41 | 42 | // minor 43 | ver -= (major * 10000); 44 | minor = (unsigned long) (ver / 100); 45 | if (minor > 99 || minor < 0) return 0; 46 | 47 | // revision 48 | ver -= (minor * 100); 49 | rev = ver; 50 | if (rev > 99 || rev < 0) return 0; 51 | 52 | printed = std::sprintf(outBuf, "%lu.%lu.%lu", major, minor, rev); 53 | if (printed < 0) return 0; 54 | outBuf[8] = '\0'; 55 | return printed; 56 | } 57 | -------------------------------------------------------------------------------- /src/bncsutil/libinfo.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Library Information 8 | * November 16, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef BNCSUTIL_LIBINFO_H 27 | #define BNCSUTIL_LIBINFO_H 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | // Library Version 34 | // Defined as follows, for library version a.b.c: 35 | // (a * 10^4) + (b * 10^2) + c 36 | // Version 1.2.0: 37 | #define BNCSUTIL_VERSION 10300 38 | 39 | // Get Version 40 | MEXP(unsigned long) bncsutil_getVersion(); 41 | 42 | // Get Version as String 43 | // Copies version into outBuf, returns number of bytes copied (or 0 on fail). 44 | // (outBuf should be at least 9 bytes long) 45 | MEXP(int) bncsutil_getVersionString(char* outbuf); 46 | 47 | #ifdef __cplusplus 48 | } // extern "C" 49 | #endif 50 | 51 | #endif /* BNCSUTIL_LIBINFO_H */ 52 | -------------------------------------------------------------------------------- /src/bncsutil/ms_stdint.h: -------------------------------------------------------------------------------- 1 | // ISO C9x compliant stdint.h for Microsoft Visual Studio 2 | // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 3 | // 4 | // Copyright (c) 2006-2008 Alexander Chemeris 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | // 9 | // 1. Redistributions of source code must retain the above copyright notice, 10 | // this list of conditions and the following disclaimer. 11 | // 12 | // 2. Redistributions in binary form must reproduce the above copyright 13 | // notice, this list of conditions and the following disclaimer in the 14 | // documentation and/or other materials provided with the distribution. 15 | // 16 | // 3. The name of the author may be used to endorse or promote products 17 | // derived from this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 20 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 22 | // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 | // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 | // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | /////////////////////////////////////////////////////////////////////////////// 31 | 32 | #ifndef _MSC_VER // [ 33 | #error "Use this header only with Microsoft Visual C++ compilers!" 34 | #endif // _MSC_VER ] 35 | 36 | #ifndef _MSC_STDINT_H_ // [ 37 | #define _MSC_STDINT_H_ 38 | 39 | #if _MSC_VER > 1000 40 | #pragma once 41 | #endif 42 | 43 | #include 44 | 45 | // For Visual Studio 6 in C++ mode wrap include with 'extern "C++" {}' 46 | // or compiler give many errors like this: 47 | // error C2733: second C linkage of overloaded function 'wmemchr' not allowed 48 | #if (_MSC_VER < 1300) && defined(__cplusplus) 49 | extern "C++" { 50 | #endif 51 | # include 52 | #if (_MSC_VER < 1300) && defined(__cplusplus) 53 | } 54 | #endif 55 | 56 | // Define _W64 macros to mark types changing their size, like intptr_t. 57 | #ifndef _W64 58 | # if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 59 | # define _W64 __w64 60 | # else 61 | # define _W64 62 | # endif 63 | #endif 64 | 65 | 66 | // 7.18.1 Integer types 67 | 68 | // 7.18.1.1 Exact-width integer types 69 | typedef __int8 int8_t; 70 | typedef __int16 int16_t; 71 | typedef __int32 int32_t; 72 | typedef __int64 int64_t; 73 | typedef unsigned __int8 uint8_t; 74 | typedef unsigned __int16 uint16_t; 75 | typedef unsigned __int32 uint32_t; 76 | typedef unsigned __int64 uint64_t; 77 | 78 | // 7.18.1.2 Minimum-width integer types 79 | typedef int8_t int_least8_t; 80 | typedef int16_t int_least16_t; 81 | typedef int32_t int_least32_t; 82 | typedef int64_t int_least64_t; 83 | typedef uint8_t uint_least8_t; 84 | typedef uint16_t uint_least16_t; 85 | typedef uint32_t uint_least32_t; 86 | typedef uint64_t uint_least64_t; 87 | 88 | // 7.18.1.3 Fastest minimum-width integer types 89 | typedef int8_t int_fast8_t; 90 | typedef int16_t int_fast16_t; 91 | typedef int32_t int_fast32_t; 92 | typedef int64_t int_fast64_t; 93 | typedef uint8_t uint_fast8_t; 94 | typedef uint16_t uint_fast16_t; 95 | typedef uint32_t uint_fast32_t; 96 | typedef uint64_t uint_fast64_t; 97 | 98 | // 7.18.1.4 Integer types capable of holding object pointers 99 | #ifdef _WIN64 // [ 100 | typedef __int64 intptr_t; 101 | typedef unsigned __int64 uintptr_t; 102 | #else // _WIN64 ][ 103 | typedef _W64 int intptr_t; 104 | typedef _W64 unsigned int uintptr_t; 105 | #endif // _WIN64 ] 106 | 107 | // 7.18.1.5 Greatest-width integer types 108 | typedef int64_t intmax_t; 109 | typedef uint64_t uintmax_t; 110 | 111 | 112 | // 7.18.2 Limits of specified-width integer types 113 | 114 | #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 115 | 116 | // 7.18.2.1 Limits of exact-width integer types 117 | #define INT8_MIN ((int8_t)_I8_MIN) 118 | #define INT8_MAX _I8_MAX 119 | #define INT16_MIN ((int16_t)_I16_MIN) 120 | #define INT16_MAX _I16_MAX 121 | #define INT32_MIN ((int32_t)_I32_MIN) 122 | #define INT32_MAX _I32_MAX 123 | #define INT64_MIN ((int64_t)_I64_MIN) 124 | #define INT64_MAX _I64_MAX 125 | #define UINT8_MAX _UI8_MAX 126 | #define UINT16_MAX _UI16_MAX 127 | #define UINT32_MAX _UI32_MAX 128 | #define UINT64_MAX _UI64_MAX 129 | 130 | // 7.18.2.2 Limits of minimum-width integer types 131 | #define INT_LEAST8_MIN INT8_MIN 132 | #define INT_LEAST8_MAX INT8_MAX 133 | #define INT_LEAST16_MIN INT16_MIN 134 | #define INT_LEAST16_MAX INT16_MAX 135 | #define INT_LEAST32_MIN INT32_MIN 136 | #define INT_LEAST32_MAX INT32_MAX 137 | #define INT_LEAST64_MIN INT64_MIN 138 | #define INT_LEAST64_MAX INT64_MAX 139 | #define UINT_LEAST8_MAX UINT8_MAX 140 | #define UINT_LEAST16_MAX UINT16_MAX 141 | #define UINT_LEAST32_MAX UINT32_MAX 142 | #define UINT_LEAST64_MAX UINT64_MAX 143 | 144 | // 7.18.2.3 Limits of fastest minimum-width integer types 145 | #define INT_FAST8_MIN INT8_MIN 146 | #define INT_FAST8_MAX INT8_MAX 147 | #define INT_FAST16_MIN INT16_MIN 148 | #define INT_FAST16_MAX INT16_MAX 149 | #define INT_FAST32_MIN INT32_MIN 150 | #define INT_FAST32_MAX INT32_MAX 151 | #define INT_FAST64_MIN INT64_MIN 152 | #define INT_FAST64_MAX INT64_MAX 153 | #define UINT_FAST8_MAX UINT8_MAX 154 | #define UINT_FAST16_MAX UINT16_MAX 155 | #define UINT_FAST32_MAX UINT32_MAX 156 | #define UINT_FAST64_MAX UINT64_MAX 157 | 158 | // 7.18.2.4 Limits of integer types capable of holding object pointers 159 | #ifdef _WIN64 // [ 160 | # define INTPTR_MIN INT64_MIN 161 | # define INTPTR_MAX INT64_MAX 162 | # define UINTPTR_MAX UINT64_MAX 163 | #else // _WIN64 ][ 164 | # define INTPTR_MIN INT32_MIN 165 | # define INTPTR_MAX INT32_MAX 166 | # define UINTPTR_MAX UINT32_MAX 167 | #endif // _WIN64 ] 168 | 169 | // 7.18.2.5 Limits of greatest-width integer types 170 | #define INTMAX_MIN INT64_MIN 171 | #define INTMAX_MAX INT64_MAX 172 | #define UINTMAX_MAX UINT64_MAX 173 | 174 | // 7.18.3 Limits of other integer types 175 | 176 | #ifdef _WIN64 // [ 177 | # define PTRDIFF_MIN _I64_MIN 178 | # define PTRDIFF_MAX _I64_MAX 179 | #else // _WIN64 ][ 180 | # define PTRDIFF_MIN _I32_MIN 181 | # define PTRDIFF_MAX _I32_MAX 182 | #endif // _WIN64 ] 183 | 184 | #define SIG_ATOMIC_MIN INT_MIN 185 | #define SIG_ATOMIC_MAX INT_MAX 186 | 187 | #ifndef SIZE_MAX // [ 188 | # ifdef _WIN64 // [ 189 | # define SIZE_MAX _UI64_MAX 190 | # else // _WIN64 ][ 191 | # define SIZE_MAX _UI32_MAX 192 | # endif // _WIN64 ] 193 | #endif // SIZE_MAX ] 194 | 195 | // WCHAR_MIN and WCHAR_MAX are also defined in 196 | #ifndef WCHAR_MIN // [ 197 | # define WCHAR_MIN 0 198 | #endif // WCHAR_MIN ] 199 | #ifndef WCHAR_MAX // [ 200 | # define WCHAR_MAX _UI16_MAX 201 | #endif // WCHAR_MAX ] 202 | 203 | #define WINT_MIN 0 204 | #define WINT_MAX _UI16_MAX 205 | 206 | #endif // __STDC_LIMIT_MACROS ] 207 | 208 | 209 | // 7.18.4 Limits of other integer types 210 | 211 | #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 212 | 213 | // 7.18.4.1 Macros for minimum-width integer constants 214 | 215 | #define INT8_C(val) val##i8 216 | #define INT16_C(val) val##i16 217 | #define INT32_C(val) val##i32 218 | #define INT64_C(val) val##i64 219 | 220 | #define UINT8_C(val) val##ui8 221 | #define UINT16_C(val) val##ui16 222 | #define UINT32_C(val) val##ui32 223 | #define UINT64_C(val) val##ui64 224 | 225 | // 7.18.4.2 Macros for greatest-width integer constants 226 | #define INTMAX_C INT64_C 227 | #define UINTMAX_C UINT64_C 228 | 229 | #endif // __STDC_CONSTANT_MACROS ] 230 | 231 | 232 | #endif // _MSC_STDINT_H_ ] 233 | -------------------------------------------------------------------------------- /src/bncsutil/mutil.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Utility Headers 8 | * October 23, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | 27 | #ifndef MUTIL_H 28 | #define MUTIL_H 29 | 30 | #define LITTLEENDIAN 1 31 | 32 | 33 | #ifdef HAVE_CONFIG_H 34 | #include 35 | #endif 36 | 37 | /* Specific-Sized Integers */ 38 | #include "mutil_types.h" 39 | #ifdef __cplusplus 40 | #include 41 | #else 42 | #include 43 | #endif 44 | 45 | // functions for converting a string to a 64-bit number. 46 | #if defined(_MSC_VER) 47 | #define ATOL64(x) _atoi64(x) 48 | #else 49 | #define ATOL64(x) atoll(x) 50 | #endif 51 | 52 | #ifdef _MSC_VER 53 | #pragma intrinsic(_lrotl,_lrotr) /* use intrinsic compiler rotations */ 54 | #define ROL(x,n) _lrotl((x),(n)) 55 | #define ROR(x,n) _lrotr((x),(n)) 56 | #else 57 | #ifndef ROL 58 | #define ROL(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) 59 | #endif 60 | #ifndef ROR 61 | #define ROR(a,b) (((a) >> (b)) | ((a) << 32 - (b))) 62 | #endif 63 | #endif 64 | 65 | #if (!defined(MUTIL_CPU_PPC)) 66 | #if (defined(__ppc__) || defined(__PPC__) || defined(powerpc) || \ 67 | defined(powerpc) || defined(ppc) || defined(_M_MPPC)) 68 | #define MUTIL_CPU_PPC 1 69 | #define MUTIL_CPU_X86 0 70 | #else 71 | #define MUTIL_CPU_PPC 0 72 | #endif 73 | #endif 74 | 75 | #if (!defined(MUTIL_CPU_X86)) 76 | #if (__INTEL__ || defined(__i386__) || defined(i386) || defined(intel) || \ 77 | defined(_M_IX86)) 78 | #define MUTIL_CPU_X86 1 79 | #ifndef MUTIL_CPU_PPC 80 | #define MUTIL_CPU_PPC 0 81 | #endif 82 | #else 83 | #define MUTIL_CPU_X86 0 84 | #endif 85 | #endif 86 | 87 | #if (!defined(BIGENDIAN)) && (!defined(LITTLEENDIAN)) 88 | #if MUTIL_CPU_PPC 89 | #define BIGENDIAN 1 90 | #define LITTLEENDIAN 0 91 | #elif MUTIL_CPU_X86 92 | #define LITTLEENDIAN 1 93 | #define BIGENDIAN 0 94 | #else 95 | #error Unable to determine byte order, define BIGENDIAN or LITTLEENDIAN. 96 | #endif 97 | #elif defined(BIGENDIAN) && (!defined(LITTLEENDIAN)) 98 | #undef BIGENDIAN 99 | #define BIGENDIAN 1 100 | #define LITTLEENDIAN 0 101 | #elif defined(LITTLEENDIAN) && (!defined(BIGENDIAN)) 102 | #undef LITTLEENDIAN 103 | #define LITTLEENDIAN 1 104 | #define BIGENDIAN 0 105 | #endif 106 | 107 | #define SWAP2(num) ((((num) >> 8) & 0x00FF) | (((num) << 8) & 0xFF00)) 108 | #define SWAP4(num) ((((num) >> 24) & 0x000000FF) | (((num) >> 8) & 0x0000FF00) | (((num) << 8) & 0x00FF0000) | (((num) << 24) & 0xFF000000)) 109 | #define SWAP8(x) \ 110 | (uint64_t)((((uint64_t)(x) & 0xff) << 56) | \ 111 | ((uint64_t)(x) & 0xff00ULL) << 40 | \ 112 | ((uint64_t)(x) & 0xff0000ULL) << 24 | \ 113 | ((uint64_t)(x) & 0xff000000ULL) << 8 | \ 114 | ((uint64_t)(x) & 0xff00000000ULL) >> 8 | \ 115 | ((uint64_t)(x) & 0xff0000000000ULL) >> 24 | \ 116 | ((uint64_t)(x) & 0xff000000000000ULL) >> 40 | \ 117 | ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) 118 | 119 | /* For those who think in bits */ 120 | #define SWAP16 SWAP2 121 | #define SWAP32 SWAP4 122 | #define SWAP64 SWAP8 123 | 124 | #if BIGENDIAN 125 | #define LSB2(num) SWAP2(num) 126 | #define LSB4(num) SWAP4(num) 127 | #define MSB2(num) (num) 128 | #define MSB4(num) (num) 129 | #else /* (little endian) */ 130 | #define LSB2(num) (num) 131 | #define LSB4(num) (num) 132 | #define MSB2(num) SWAP2(num) 133 | #define MSB4(num) SWAP4(num) 134 | #endif /* (endianness) */ 135 | 136 | #ifndef MOS_WINDOWS 137 | /* attempt automatic Windows detection */ 138 | #ifdef _MSC_VER 139 | /* Microsoft C++ compiler, has to be windows */ 140 | #define MOS_WINDOWS 141 | #else 142 | #if defined(_WIN) || defined(_WINDOWS) || defined(WINDOWS) || \ 143 | defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64) 144 | #define MOS_WINDOWS 145 | #endif 146 | #endif 147 | #endif 148 | 149 | #if !(defined(MUTIL_LIB_BUILD)) && defined(BNCSUTIL_EXPORTS) 150 | # define MUTIL_LIB_BUILD 151 | #endif 152 | 153 | /** 154 | * I think what this tries to do is differentiate if you are trying to build 155 | * this as a library exporting symbols versus using the library from this same project 156 | * ..which I don't think makes much sense. TODO: evaluate and nuke import part in the future 157 | */ 158 | #ifdef MOS_WINDOWS 159 | # pragma comment(lib, "Version.lib") 160 | # ifdef MUTIL_LIB_BUILD 161 | # define MEXP(type) __declspec(dllexport) type __cdecl 162 | # define MCEXP(name) class __declspec(dllexport) name 163 | # else 164 | # define MEXP(type) __declspec(dllimport) type __cdecl 165 | # define MCEXP(name) class __declspec(dllimport) name 166 | # endif 167 | #else 168 | # ifdef MUTIL_LIB_BUILD 169 | # define MEXP(type) type 170 | # define MCEXP(name) class name 171 | # else 172 | # define MEXP(type) extern type 173 | # define MCEXP(name) class name 174 | # endif 175 | #endif 176 | #define MYRIAD_UTIL 177 | 178 | #ifndef NULL 179 | #define NULL 0 180 | #endif /* NULL */ 181 | 182 | #endif /* MUTIL_H */ 183 | -------------------------------------------------------------------------------- /src/bncsutil/mutil_types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Integer Types 8 | * November 12, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef BNCSUTIL_MUTIL_TYPES_H_INCLUDED 27 | #define BNCSUTIL_MUTIL_TYPES_H_INCLUDED 28 | 29 | #if defined(_MSC_VER) && (defined(HAVE_STDINT_H) && !HAVE_STDINT_H) 30 | #include "ms_stdint.h" 31 | #else 32 | #ifdef __cplusplus 33 | #include 34 | #else 35 | #include 36 | #endif 37 | #endif 38 | 39 | #endif /* BNCSUTIL_MUTIL_TYPES_H_INCLUDED */ 40 | -------------------------------------------------------------------------------- /src/bncsutil/nls.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * New Logon System (SRP) Interface 8 | * November 26, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef BNCSUTIL_NLS_H_INCLUDED 27 | #define BNCSUTIL_NLS_H_INCLUDED 28 | 29 | #include 30 | 31 | // modulus ("N") in base-16 32 | #define NLS_VAR_N_STR \ 33 | "F8FF1A8B619918032186B68CA092B5557E976C78C73212D91216F6658523C787" 34 | // generator var ("g") 35 | #define NLS_VAR_g 0x2F 36 | // SHA1(g) ^ SHA1(N) ("I") 37 | #define NLS_VAR_I_STR "8018CF0A425BA8BEB8958B1AB6BF90AED970E6C" 38 | // Server Signature Key 39 | #define NLS_SIGNATURE_KEY 0x10001 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | /** 46 | * Data type used by NLS functions. 47 | */ 48 | typedef struct _nls nls_t; 49 | 50 | /** 51 | * Allocates and initializes an nls_t structure. 52 | * Returns a NULL pointer on failure. 53 | */ 54 | MEXP(nls_t*) nls_init(const char* username, const char* password); 55 | 56 | /** 57 | * Allocates and initializes an nls_t structure, using the given string lengths. 58 | * Returns a NULL pointer on failure. 59 | * (Lengths do not include the null-terminator.) 60 | */ 61 | MEXP(nls_t*) nls_init_l(const char* username, unsigned long username_length, 62 | const char* password, unsigned long password_length); 63 | 64 | /** 65 | * Frees an nls_t structure. 66 | */ 67 | MEXP(void) nls_free(nls_t* nls); 68 | 69 | /** 70 | * Re-initializes an nls_t structure with a new username and 71 | * password. Returns the nls argument on success or a NULL 72 | * pointer on failure. 73 | */ 74 | MEXP(nls_t*) nls_reinit(nls_t* nls, const char* username, 75 | const char* password); 76 | 77 | /** 78 | * Re-initializes an nls_t structure with a new username and 79 | * password and their given lengths. Returns the nls argument 80 | * on success or a NULL pointer on failure. 81 | */ 82 | MEXP(nls_t*) nls_reinit_l(nls_t* nls, const char* username, 83 | unsigned long username_length, const char* password, 84 | unsigned long password_length); 85 | 86 | /* Packet Generation Functions */ 87 | 88 | /** 89 | * Builds the content of an SID_AUTH_ACCOUNTCREATE packet. 90 | * buf should be at least strlen(username) + 65 bytes long. 91 | * bufSize should be the size of buf. 92 | * Returns the number of bytes placed in buf, or 0 on error. 93 | */ 94 | MEXP(unsigned long) nls_account_create(nls_t* nls, char* buf, unsigned long bufSize); 95 | 96 | /** 97 | * [ DEPRECATED ] Uses the internal username buffer when 98 | * generating the packet, which is in all 99 | * upper-case. 100 | * 101 | * Builds the content of an SID_AUTH_ACCOUNTLOGON packet. 102 | * buf should be at least strlen(username) + 33 bytes long. 103 | * bufSize should be size of buf. 104 | * Returns the number of bytes placed in buf, or 0 on error. 105 | */ 106 | MEXP(unsigned long) nls_account_logon(nls_t* nls, char* buf, unsigned long bufSize); 107 | 108 | /** 109 | * NOTE 110 | * There is no nls_account_logon_proof function, as it'd be the same as 111 | * nls_get_M1, and no nls_account_change function, as it's probably easier to 112 | * just assemble that packet yourself. 113 | */ 114 | 115 | /** 116 | * Builds the content of an SID_AUTH_ACCOUNTCHANGEPROOF packet and places it in 117 | * buf, which should be at least 84 bytes long. The account's new password 118 | * should be placed in new_password. A new nls_t* pointer will be returned 119 | * as if you'd called nls_init. If you're not going to check the server 120 | * password proof (the response to this packet) then you can nls_free the value 121 | * of nls and use the returned value. Any login operations with the new 122 | * password should use the returned value. Returns a NULL pointer on error. 123 | */ 124 | MEXP(nls_t*) nls_account_change_proof(nls_t* nls, char* buf, 125 | const char* new_password, const char* B, const char* salt); 126 | 127 | /* Calculation Functions */ 128 | 129 | /** 130 | * Gets the "secret" value (S). (32 bytes) 131 | */ 132 | MEXP(void) nls_get_S(nls_t* nls, char* out, const char* B, const char* salt); 133 | 134 | /** 135 | * Gets the password verifier (v). (32 bytes) 136 | */ 137 | MEXP(void) nls_get_v(nls_t* nls, char* out, const char* salt); 138 | 139 | /** 140 | * Gets the public key (A). (32 bytes) 141 | */ 142 | MEXP(void) nls_get_A(nls_t* nls, char* out); 143 | 144 | /** 145 | * Gets "K" value, which is based on the secret (S). 146 | * The buffer "out" must be at least 40 bytes long. 147 | */ 148 | MEXP(void) nls_get_K(nls_t* nls, char* out, const char* S); 149 | 150 | /** 151 | * Gets the "M[1]" value, which proves that you know your password. 152 | * The buffer "out" must be at least 20 bytes long. 153 | */ 154 | MEXP(void) nls_get_M1(nls_t* nls, char* out, const char* B, const char* salt); 155 | 156 | /** 157 | * Checks the "M[2]" value, which proves that the server knows your 158 | * password. Pass the M2 value in the var_M2 argument. Returns 0 159 | * if the check failed, nonzero if the proof matches. Now that 160 | * calculated value caching has been added, B and salt can be 161 | * safely set to NULL. 162 | */ 163 | MEXP(int) nls_check_M2(nls_t* nls, const char* var_M2, const char* B, 164 | const char* salt); 165 | 166 | /** 167 | * Checks the server signature received in SID_AUTH_INFO (0x50). 168 | * Pass the IPv4 address of the server you're connecting to in the address 169 | * paramater and the 128-byte server signature in the signature_raw paramater. 170 | * Address paramater should be in network byte order (big-endian). 171 | * Returns a nonzero value if the signature matches or 0 on failure. 172 | * Note that this function does NOT take an nls_t* argument! 173 | */ 174 | MEXP(int) nls_check_signature(uint32_t address, const char* signature_raw); 175 | 176 | #ifdef __cplusplus 177 | } // extern "C" 178 | 179 | #include 180 | #include 181 | #include 182 | 183 | /** 184 | * NLS convenience class. Getter functions which return pointers return those 185 | * pointers from dynamically-allocated memory that will be automatically freed 186 | * when the NLS object is destroyed. They should not be free()'d or deleted. 187 | */ 188 | class NLS 189 | { 190 | public: 191 | NLS(const char* username, const char* password) : n((nls_t*) 0) 192 | { 193 | n = nls_init(username, password); 194 | } 195 | 196 | NLS(const char* username, size_t username_length, const char* password, 197 | size_t password_length) 198 | { 199 | n = nls_init_l(username, username_length, password, password_length); 200 | } 201 | 202 | NLS(const std::string& username, const std::string& password) 203 | { 204 | n = nls_init_l(username.c_str(), username.length(), 205 | password.c_str(), password.length()); 206 | } 207 | 208 | virtual ~NLS() 209 | { 210 | std::vector::iterator i; 211 | 212 | if (n) 213 | nls_free(n); 214 | 215 | for (i = blocks.begin(); i != blocks.end(); i++) { 216 | delete [] *i; 217 | } 218 | } 219 | 220 | void getSecret(char* out, const char* salt, const char* B) 221 | { 222 | nls_get_S(n, out, B, salt); 223 | } 224 | 225 | const char* getSecret(const char* salt, const char* B) 226 | { 227 | char* buf = allocateBuffer(32); 228 | getSecret(buf, salt, B); 229 | return buf; 230 | } 231 | 232 | void getVerifier(char* out, const char* salt) 233 | { 234 | nls_get_v(n, out, salt); 235 | } 236 | 237 | const char* getVerifier(const char* salt) 238 | { 239 | char* buf = allocateBuffer(32); 240 | getVerifier(buf, salt); 241 | return buf; 242 | } 243 | 244 | void getPublicKey(char* out) 245 | { 246 | nls_get_A(n, out); 247 | } 248 | 249 | const char* getPublicKey(void) 250 | { 251 | char* buf = allocateBuffer(32); 252 | getPublicKey(buf); 253 | return buf; 254 | } 255 | 256 | void getHashedSecret(char* out, const char* secret) 257 | { 258 | nls_get_K(n, out, secret); 259 | } 260 | 261 | const char* getHashedSecret(const char* secret) 262 | { 263 | char* buf = allocateBuffer(40); 264 | getHashedSecret(buf, secret); 265 | return buf; 266 | } 267 | 268 | void getClientSessionKey(char* out, const char* salt, const char* B) 269 | { 270 | nls_get_M1(n, out, B, salt); 271 | } 272 | 273 | const char* getClientSessionKey(const char* salt, const char* B) 274 | { 275 | char* buf = allocateBuffer(20); 276 | getClientSessionKey(buf, salt, B); 277 | return buf; 278 | } 279 | 280 | bool checkServerSessionKey(const char* key, const char* salt, 281 | const char* B) 282 | { 283 | return (nls_check_M2(n, key, B, salt) != 0); 284 | } 285 | 286 | NLS makeChangeProof(char* buf, const char* new_password, const char* salt, 287 | const char* B) 288 | { 289 | return NLS(nls_account_change_proof(n, buf, new_password, B, salt)); 290 | } 291 | 292 | NLS makeChangeProof(char* buf, const std::string& new_password, 293 | const char* salt, const char* B) 294 | { 295 | return NLS(nls_account_change_proof(n, buf, new_password.c_str(), B, 296 | salt)); 297 | } 298 | 299 | std::pair makeChangeProof(const char* new_password, 300 | const char* salt, const char* B) 301 | { 302 | char* buf = allocateBuffer(84); 303 | NLS nls = NLS(nls_account_change_proof(n, buf, new_password, B, salt)); 304 | return std::pair(nls, buf); 305 | } 306 | 307 | std::pair makeChangeProof(const std::string& new_password, 308 | const char* salt, const char* B) 309 | { 310 | return makeChangeProof(new_password.c_str(), salt, B); 311 | } 312 | private: 313 | std::vector blocks; 314 | nls_t* n; 315 | 316 | NLS(nls_t* nls) 317 | { 318 | n = nls; 319 | } 320 | 321 | char* allocateBuffer(size_t length) 322 | { 323 | char* buf = new char[length]; 324 | blocks.push_back(buf); 325 | return buf; 326 | } 327 | }; 328 | 329 | #endif 330 | 331 | #endif /* BNCSUTIL_NLS_H_INCLUDED */ 332 | -------------------------------------------------------------------------------- /src/bncsutil/oldauth.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Old Logon System Implementation 8 | * October 23, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #include // for MEXP() 27 | #include 28 | #include 29 | #include // for strlen 30 | 31 | /** 32 | * Double-hashes the given password using the given 33 | * server and client tokens. 34 | * 35 | * outBuffer MUST be at least 20 bytes long. 36 | */ 37 | MEXP(void) doubleHashPassword(const char* password, uint32_t clientToken, 38 | uint32_t serverToken, char* outBuffer) { 39 | char intermediate[28]; 40 | uint32_t* lp; 41 | 42 | calcHashBuf(password, std::strlen(password), intermediate + 8); 43 | lp = (uint32_t*) &intermediate; 44 | lp[0] = clientToken; 45 | lp[1] = serverToken; 46 | calcHashBuf(intermediate, 28, outBuffer); 47 | 48 | #if DEBUG 49 | bncsutil_debug_message_a("doubleHashPassword(\"%s\", 0x%08X, 0x%08X) =", 50 | password, clientToken, serverToken); 51 | bncsutil_debug_dump(outBuffer, 20); 52 | #endif 53 | } 54 | 55 | /** 56 | * Single-hashes the password for account creation and password changes. 57 | * 58 | * outBuffer MUST be at least 20 bytes long. 59 | */ 60 | MEXP(void) hashPassword(const char* password, char* outBuffer) { 61 | calcHashBuf(password, std::strlen(password), outBuffer); 62 | 63 | #if DEBUG 64 | bncsutil_debug_message_a("hashPassword(\"%s\") =", password); 65 | bncsutil_debug_dump(outBuffer, 20); 66 | #endif 67 | } 68 | -------------------------------------------------------------------------------- /src/bncsutil/oldauth.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Old Logon System 8 | * October 23, 2004 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef BNCSUTIL_OLDAUTH_H 27 | #define BNCSUTIL_OLDAUTH_H 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * Double-hashes the given password using the given 35 | * server and client tokens. 36 | */ 37 | MEXP(void) doubleHashPassword(const char* password, uint32_t clientToken, 38 | uint32_t serverToken, char* outBuffer); 39 | 40 | /** 41 | * Single-hashes the password for account creation and password changes. 42 | */ 43 | MEXP(void) hashPassword(const char* password, char* outBuffer); 44 | 45 | #ifdef __cplusplus 46 | } // extern "C" 47 | #endif 48 | 49 | #endif /* BNCSUTIL_OLDAUTH_H */ 50 | -------------------------------------------------------------------------------- /src/bncsutil/pe.c: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Portable Executable Processing 8 | * August 16, 2005 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | int cm_pe_load_resdir(FILE* f, uint32_t offset, cm_pe_resdir_t* dir); 32 | 33 | MEXP(cm_pe_t) cm_pe_load(const char* filename) 34 | { 35 | cm_pe_t pe; 36 | cm_pe_header_t* header; 37 | cm_pe_optional_header_t* opt_header; 38 | cm_pe_windows_header_t* win_header; 39 | long pe_offset = 0; 40 | //size_t i; 41 | size_t count; 42 | 43 | pe = (cm_pe_t) malloc(sizeof(struct cm_pe)); 44 | if (!pe) 45 | return (cm_pe_t) 0; 46 | 47 | memset(pe, 0, sizeof(struct cm_pe)); 48 | 49 | pe->f = fopen(filename, "r"); 50 | if (!pe->f) { 51 | free(pe); 52 | return (cm_pe_t) 0; 53 | } 54 | 55 | if (fseek(pe->f, 0x3CL, SEEK_SET) == -1) 56 | goto err_trap; 57 | 58 | if (fread(&pe_offset, 4, 1, pe->f) != 1) 59 | goto err_trap; 60 | 61 | #if BIG_ENDIAN 62 | pe_offset = LSB4(pe_offset); 63 | #endif 64 | 65 | if (fseek(pe->f, pe_offset, SEEK_SET) == -1) 66 | goto err_trap; 67 | 68 | if (fread(&pe->header, sizeof(cm_pe_header_t), 1, pe->f) != 1) 69 | goto err_trap; 70 | 71 | header = &pe->header; 72 | #if BIGENDIAN 73 | /* Without regular expressions, this would've sucked. */ 74 | header->signature = SWAP32(header->signature); 75 | header->machine = SWAP16(header->machine); 76 | header->section_count = SWAP16(header->section_count); 77 | header->timestamp = SWAP32(header->timestamp); 78 | header->symbol_table_offset = SWAP32(header->symbol_table_offset); 79 | header->symbol_count = SWAP32(header->symbol_count); 80 | header->optional_header_size = SWAP16(header->optional_header_size); 81 | header->characteristics = SWAP16(header->characteristics); 82 | #endif 83 | 84 | if (header->optional_header_size > 0) { 85 | if (fread(&pe->optional_header, PE_OPTIONAL_HEADER_MIN_SIZE, 1, pe->f) 86 | != 1) 87 | { 88 | goto err_trap; 89 | } 90 | 91 | opt_header = &pe->optional_header; 92 | win_header = &pe->windows_header; 93 | 94 | #if BIGENDIAN 95 | opt_header->magic = SWAP16(opt_header->magic); 96 | #endif 97 | 98 | if (opt_header->magic == IMAGE_FORMAT_PE32) { 99 | if (fread(&opt_header->data_base, 4, 1, pe->f) != 1) 100 | goto err_trap; 101 | if (fread(&win_header->image_base, 4, 1, pe->f) != 1) 102 | goto err_trap; 103 | // The 40 is not a typo. 104 | if (fread(&win_header->section_alignment, 40, 1, pe->f) != 1) 105 | goto err_trap; 106 | if (fread(&win_header->stack_reserve_size, 4, 1, pe->f) != 1) 107 | goto err_trap; 108 | if (fread(&win_header->stack_commit_size, 4, 1, pe->f) != 1) 109 | goto err_trap; 110 | if (fread(&win_header->heap_reserve_size, 4, 1, pe->f) != 1) 111 | goto err_trap; 112 | if (fread(&win_header->heap_commit_size, 4, 1, pe->f) != 1) 113 | goto err_trap; 114 | if (fread(&win_header->loader_flags, 4, 1, pe->f) != 1) 115 | goto err_trap; 116 | if (fread(&win_header->data_directory_count, 4, 1, pe->f) != 1) 117 | goto err_trap; 118 | } else if (opt_header->magic == IMAGE_FORMAT_PE32_PLUS) { 119 | if (fread(win_header, sizeof(cm_pe_windows_header_t), 1, pe->f)!= 1) 120 | goto err_trap; 121 | } else { 122 | goto err_trap; 123 | } 124 | 125 | #if BIGENDIAN 126 | opt_header->code_section_size = SWAP32(opt_header->code_section_size); 127 | opt_header->initialized_data_size = 128 | SWAP32(opt_header->initialized_data_size); 129 | opt_header->uninitialized_data_size = 130 | SWAP32(opt_header->uninitialized_data_size); 131 | opt_header->entry_point = SWAP32(opt_header->entry_point); 132 | opt_header->code_base = SWAP32(opt_header->code_base); 133 | opt_header->data_base = SWAP32(opt_header->data_base); 134 | 135 | win_header->image_base = SWAP64(win_header->image_base); 136 | win_header->section_alignment = SWAP32(win_header->section_alignment); 137 | win_header->file_alignment = SWAP32(win_header->file_alignment); 138 | win_header->major_os_version = SWAP16(win_header->major_os_version); 139 | win_header->minor_os_version = SWAP16(win_header->minor_os_version); 140 | win_header->major_image_version = 141 | SWAP16(win_header->major_image_version); 142 | win_header->minor_image_version = 143 | SWAP16(win_header->minor_image_version); 144 | win_header->major_subsystem_version = 145 | SWAP16(win_header->major_subsystem_version); 146 | win_header->minor_subsystem_version = 147 | SWAP16(win_header->minor_subsystem_version); 148 | win_header->reserved = SWAP32(win_header->reserved); 149 | win_header->image_size = SWAP32(win_header->image_size); 150 | win_header->headers_size = SWAP32(win_header->headers_size); 151 | win_header->checksum = SWAP32(win_header->checksum); 152 | win_header->subsystem = SWAP16(win_header->subsystem); 153 | win_header->dll_characteristics = 154 | SWAP16(win_header->dll_characteristics); 155 | win_header->stack_reserve_size = SWAP64(win_header->stack_reserve_size); 156 | win_header->stack_commit_size = SWAP64(win_header->stack_commit_size); 157 | win_header->heap_reserve_size = SWAP64(win_header->heap_reserve_size); 158 | win_header->heap_commit_size = SWAP64(win_header->heap_commit_size); 159 | win_header->loader_flags = SWAP32(win_header->loader_flags); 160 | win_header->data_directory_count = 161 | SWAP32(win_header->data_directory_count); 162 | #endif 163 | 164 | if (win_header->data_directory_count > 0) { 165 | count = win_header->data_directory_count; 166 | pe->data_directories = (cm_pe_data_directory_t*) 167 | calloc(sizeof(cm_pe_data_directory_t), count); 168 | 169 | if (!pe->data_directories) 170 | goto err_trap; 171 | 172 | if (fread(pe->data_directories, sizeof(cm_pe_data_directory_t), 173 | count, pe->f) != count) 174 | { 175 | goto dir_err_trap; 176 | } 177 | 178 | #if BIGENDIAN 179 | for (i = 0; i < count; i++) { 180 | pe->data_directories[i].rva = 181 | SWAP32(pe->data_directories[i].rva); 182 | pe->data_directories[i].size = 183 | SWAP32(pe->data_directories[i].size); 184 | } 185 | #endif 186 | } 187 | 188 | count = (size_t) header->section_count; 189 | if (count) { 190 | pe->sections = (cm_pe_section_t*) calloc(sizeof(cm_pe_section_t), 191 | count); 192 | 193 | if (!pe->sections) 194 | goto dir_err_trap; 195 | 196 | if (fread(pe->sections, sizeof(cm_pe_section_t), count, pe->f) 197 | != count) 198 | { 199 | goto sect_err_trap; 200 | } 201 | } 202 | 203 | #if BIGENDIAN 204 | for (i = 0; i < count; i++) { 205 | pe->sections[i].virtual_size = SWAP32(pe->sections[i].virtual_size); 206 | pe->sections[i].virtual_address = 207 | SWAP32(pe->sections[i].virtual_address); 208 | pe->sections[i].raw_data_size = 209 | SWAP32(pe->sections[i].raw_data_size); 210 | pe->sections[i].raw_data_offset = 211 | SWAP32(pe->sections[i].raw_data_offset); 212 | pe->sections[i].relocations_offset = 213 | SWAP32(pe->sections[i].relocations_offset); 214 | pe->sections[i].line_numbers_offset = 215 | SWAP32(pe->sections[i].line_numbers_offset); 216 | pe->sections[i].relocation_count = 217 | SWAP16(pe->sections[i].relocation_count); 218 | pe->sections[i].line_number_count = 219 | SWAP16(pe->sections[i].line_number_count); 220 | pe->sections[i].characteristics = 221 | SWAP32(pe->sections[i].characteristics); 222 | } 223 | #endif 224 | } 225 | 226 | return pe; 227 | sect_err_trap: 228 | free(pe->sections); 229 | dir_err_trap: 230 | free(pe->data_directories); 231 | err_trap: 232 | fclose(pe->f); 233 | free(pe); 234 | return (cm_pe_t) 0; 235 | } 236 | 237 | MEXP(void) cm_pe_unload(cm_pe_t pe) 238 | { 239 | if (pe->data_directories) 240 | free(pe->data_directories); 241 | if (pe->sections) 242 | free(pe->sections); 243 | if (pe->f) 244 | fclose(pe->f); 245 | free(pe); 246 | } 247 | 248 | MEXP(cm_pe_section_t*) cm_pe_get_section(cm_pe_t pe, const char* name) { 249 | unsigned int i; 250 | cm_pe_section_t* s; 251 | uint32_t section_count = pe->header.section_count; 252 | 253 | if (!pe || !pe->sections) 254 | return (cm_pe_section_t*) 0; 255 | 256 | for (i = 0, s = pe->sections; i < section_count; i++, s++) { 257 | if (strcmp(s->name, name) == 0) 258 | return s; 259 | } 260 | 261 | return (cm_pe_section_t*) 0; 262 | } 263 | 264 | MEXP(cm_pe_resdir_t*) cm_pe_load_resources(cm_pe_t pe) 265 | { 266 | cm_pe_section_t* sect; 267 | cm_pe_resdir_t* root = (cm_pe_resdir_t*) 0; 268 | cm_pe_resdir_t* dir; 269 | cm_pe_resdir_t* subdirs; 270 | cm_pe_res_t res; 271 | cm_pe_res_t* resources; 272 | cm_stack_t stack; 273 | size_t i; 274 | uint32_t base; 275 | 276 | // no need to check validity of pe pointer; cm_pe_get_section does this 277 | sect = cm_pe_get_section(pe, ".rsrc"); 278 | if (!sect) 279 | return (cm_pe_resdir_t*) 0; 280 | 281 | root = (cm_pe_resdir_t*) malloc(sizeof(cm_pe_resdir_t)); 282 | if (!root) 283 | return (cm_pe_resdir_t*) 0; 284 | 285 | base = sect->raw_data_offset; 286 | if (!cm_pe_load_resdir(pe->f, base, root)) { 287 | free(root); 288 | return (cm_pe_resdir_t*) 0; 289 | } 290 | 291 | stack = cm_stack_create(); 292 | if (!stack) { 293 | free(root); 294 | return (cm_pe_resdir_t*) 0; 295 | } 296 | 297 | cm_stack_push(stack, root); 298 | 299 | while ( (dir = (cm_pe_resdir_t*) cm_stack_pop(stack)) ) { 300 | while (dir->subdir_count + dir->resource_count < 301 | dir->named_entry_count + dir->id_entry_count) 302 | { 303 | if (fseek(pe->f, dir->offset, SEEK_SET) == -1) { 304 | cm_pe_unload_resources(root); 305 | cm_stack_destroy(stack); 306 | return (cm_pe_resdir_t*) 0; 307 | } 308 | 309 | if (fread(&res, CM_RES_REAL_SIZE, 1, pe->f) != 1) { 310 | cm_pe_unload_resources(root); 311 | cm_stack_destroy(stack); 312 | return (cm_pe_resdir_t*) 0; 313 | } 314 | 315 | #if BIGENDIAN 316 | res.name = SWAP4(res.name); 317 | res.offset = SWAP4(res.offset); 318 | #endif 319 | if (res.offset & 0x80000000) { 320 | // subdirectory 321 | i = dir->subdir_count++; 322 | subdirs = (cm_pe_resdir_t*) realloc(dir->subdirs, 323 | sizeof(cm_pe_resdir_t) * dir->subdir_count); 324 | if (!subdirs) { 325 | cm_pe_unload_resources(root); 326 | cm_stack_destroy(stack); 327 | return (cm_pe_resdir_t*) 0; 328 | } 329 | dir->subdirs = subdirs; 330 | 331 | cm_stack_push(stack, dir); 332 | dir->offset += CM_RES_REAL_SIZE; 333 | dir = (subdirs + i); 334 | 335 | res.offset &= 0x7FFFFFFF; 336 | res.file_offset = base + res.offset; 337 | 338 | if (!cm_pe_load_resdir(pe->f, res.file_offset, dir)) { 339 | cm_pe_unload_resources(root); 340 | cm_stack_destroy(stack); 341 | return (cm_pe_resdir_t*) 0; 342 | } 343 | dir->name = res.name; 344 | 345 | cm_stack_push(stack, dir); 346 | break; 347 | } 348 | // real resource 349 | res.file_offset = base + res.offset; 350 | i = dir->resource_count++; 351 | resources = (cm_pe_res_t*) realloc(dir->resources, 352 | sizeof(cm_pe_res_t) * dir->resource_count); 353 | if (!resources) { 354 | cm_pe_unload_resources(root); 355 | cm_stack_destroy(stack); 356 | return (cm_pe_resdir_t*) 0; 357 | } 358 | dir->resources = resources; 359 | memcpy(dir->resources + i, &res, sizeof(cm_pe_res_t)); 360 | dir->offset += CM_RES_REAL_SIZE; 361 | } 362 | } 363 | 364 | cm_stack_destroy(stack); 365 | return root; 366 | } 367 | 368 | MEXP(int) cm_pe_unload_resources(cm_pe_resdir_t* root) 369 | { 370 | cm_pe_resdir_t* dir; 371 | cm_stack_t stack; 372 | 373 | stack = cm_stack_create(); 374 | if (!stack) 375 | return 0; 376 | 377 | cm_stack_push(stack, root); 378 | 379 | while ( (dir = cm_stack_pop(stack)) ) { 380 | if (dir->subdir_count) { 381 | dir->subdir_count--; 382 | cm_stack_push(stack, dir); 383 | cm_stack_push(stack, (dir->subdirs + dir->subdir_count)); 384 | continue; 385 | } 386 | 387 | if (dir->subdirs) { 388 | free(dir->subdirs); 389 | dir->subdirs = (cm_pe_resdir_t*) 0; 390 | } 391 | 392 | if (dir->resources) { 393 | free(dir->resources); 394 | dir->resource_count = 0; 395 | } 396 | } 397 | 398 | cm_stack_destroy(stack); 399 | free(root); 400 | return 1; 401 | } 402 | 403 | MEXP(int) cm_pe_fixed_version(cm_pe_t pe, cm_pe_res_t* res, 404 | cm_pe_version_t* ver) 405 | { 406 | // find ".rsrc" section 407 | cm_pe_section_t* sect = pe->sections; 408 | { 409 | int i=0; 410 | for(; iheader.section_count; ++i) 411 | { 412 | if(strncmp(sect[i].name,".rsrc",sizeof(sect[i].name))==0) 413 | { 414 | sect = §[i]; 415 | break; 416 | } 417 | } 418 | if(i == pe->header.section_count) // no resources ??? 419 | return 0; 420 | } 421 | #if BIGENDIAN 422 | uint32_t check = 0xBD04EFFE; 423 | #else 424 | uint32_t check = 0xFEEF04BD; 425 | #endif 426 | uint32_t rva; 427 | uint32_t size; 428 | uint32_t offset; 429 | 430 | if (!pe || !res || !ver) 431 | return 0; 432 | 433 | if (fseek(pe->f, res->file_offset, SEEK_SET) == -1) 434 | return 0; 435 | if (fread(&rva, 4, 1, pe->f) != 1) 436 | return 0; 437 | if (fread(&size, 4, 1, pe->f) != 1) 438 | return 0; 439 | #if BIGENDIAN 440 | rva = SWAP4(rva); 441 | size = SWAP4(size); 442 | #endif 443 | 444 | offset = sect->raw_data_offset + (rva - sect->virtual_address) + 0x26; 445 | offset = (offset+3) & 0xFFFFFFFC; // align 4 byte 446 | if (fseek(pe->f, offset, SEEK_SET) == -1) 447 | return 0; 448 | if (fread(ver, sizeof(cm_pe_version_t), 1, pe->f) != 1) 449 | return 0; 450 | 451 | if (ver->dwSignature != check) 452 | return 0; 453 | 454 | #if BIGENDIAN 455 | ver->dwSignature = SWAP32(ver->dwSignature); 456 | ver->dwStrucVersion = SWAP32(ver->dwStrucVersion); 457 | ver->dwFileVersionMS = SWAP32(ver->dwFileVersionMS); 458 | ver->dwFileVersionLS = SWAP32(ver->dwFileVersionLS); 459 | ver->dwProductVersionMS = SWAP32(ver->dwProductVersionMS); 460 | ver->dwProductVersionLS = SWAP32(ver->dwProductVersionLS); 461 | ver->dwFileFlagsMask = SWAP32(ver->dwFileFlagsMask); 462 | ver->dwFileFlags = SWAP32(ver->dwFileFlags); 463 | ver->dwFileOS = SWAP32(ver->dwFileOS); 464 | ver->dwFileType = SWAP32(ver->dwFileType); 465 | ver->dwFileSubtype = SWAP32(ver->dwFileSubtype); 466 | ver->dwFileDateMS = SWAP32(ver->dwFileDateMS); 467 | ver->dwFileDateLS = SWAP32(ver->dwFileDateLS); 468 | #endif 469 | 470 | return 1; 471 | } 472 | 473 | int cm_pe_load_resdir(FILE* f, uint32_t offset, cm_pe_resdir_t* dir) 474 | { 475 | memset(dir, 0, sizeof(cm_pe_resdir_t)); 476 | 477 | if (fseek(f, offset, SEEK_SET) == -1) 478 | return 0; 479 | 480 | if (fread(dir, 16, 1, f) != 1) 481 | return 0; 482 | 483 | #if BIGENDIAN 484 | dir->characteristics = SWAP32(dir->characteristics); 485 | dir->timestamp = SWAP32(dir->timestamp); 486 | dir->major_version = SWAP16(dir->major_version); 487 | dir->minor_version = SWAP16(dir->minor_version); 488 | dir->named_entry_count = SWAP16(dir->named_entry_count); 489 | dir->id_entry_count = SWAP16(dir->id_entry_count); 490 | #endif 491 | 492 | dir->offset = (uint32_t) ftell(f); 493 | 494 | return 1; 495 | } 496 | -------------------------------------------------------------------------------- /src/bncsutil/pe.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Portable Executable Processing 8 | * August 16, 2005 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef CM_PE_H_INCLUDED 27 | #define CM_PE_H_INCLUDED 1 28 | 29 | #include "mutil.h" 30 | #ifdef __cplusplus 31 | #include 32 | #else 33 | #include 34 | #endif 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | typedef struct cm_pe_header { 41 | uint32_t signature; 42 | uint16_t machine; // IMAGE_FILE_MACHINE_* 43 | uint16_t section_count; 44 | uint32_t timestamp; 45 | uint32_t symbol_table_offset; 46 | uint32_t symbol_count; 47 | uint16_t optional_header_size; 48 | uint16_t characteristics; 49 | } cm_pe_header_t; 50 | 51 | #define IMAGE_FORMAT_PE32 0x10B 52 | #define IMAGE_FORMAT_PE32_PLUS 0x20B 53 | 54 | typedef struct cm_pe_optional_header { 55 | uint16_t magic; // image format (PE32/PE32+) 56 | uint8_t major_linker_version; 57 | uint8_t minor_linker_version; 58 | uint32_t code_section_size; 59 | uint32_t initialized_data_size; 60 | uint32_t uninitialized_data_size; 61 | uint32_t entry_point; 62 | uint32_t code_base; 63 | uint32_t data_base; // not present in PE32+! 64 | } cm_pe_optional_header_t; 65 | 66 | #define PE_OPTIONAL_HEADER_MIN_SIZE (sizeof(cm_pe_optional_header_t) - 4) 67 | 68 | typedef struct cm_pe_windows_header { 69 | uint64_t image_base; 70 | uint32_t section_alignment; 71 | uint32_t file_alignment; 72 | uint16_t major_os_version; 73 | uint16_t minor_os_version; 74 | uint16_t major_image_version; 75 | uint16_t minor_image_version; 76 | uint16_t major_subsystem_version; 77 | uint16_t minor_subsystem_version; 78 | uint32_t reserved; 79 | uint32_t image_size; 80 | uint32_t headers_size; 81 | uint32_t checksum; 82 | uint16_t subsystem; 83 | uint16_t dll_characteristics; 84 | uint64_t stack_reserve_size; 85 | uint64_t stack_commit_size; 86 | uint64_t heap_reserve_size; 87 | uint64_t heap_commit_size; 88 | uint32_t loader_flags; 89 | uint32_t data_directory_count; 90 | } cm_pe_windows_header_t; 91 | 92 | typedef struct cm_pe_data_directory { 93 | uint32_t rva; 94 | uint32_t size; 95 | } cm_pe_data_directory_t; 96 | 97 | typedef struct cm_pe_section { 98 | char name[8]; 99 | uint32_t virtual_size; 100 | uint32_t virtual_address; 101 | uint32_t raw_data_size; 102 | uint32_t raw_data_offset; 103 | uint32_t relocations_offset; 104 | uint32_t line_numbers_offset; 105 | uint16_t relocation_count; 106 | uint16_t line_number_count; 107 | uint32_t characteristics; 108 | } cm_pe_section_t; 109 | 110 | typedef struct VS_FIXEDFILEINFO { 111 | uint32_t dwSignature; 112 | uint32_t dwStrucVersion; 113 | uint32_t dwFileVersionMS; 114 | uint32_t dwFileVersionLS; 115 | union { 116 | struct { 117 | uint32_t dwProductVersionMS; 118 | uint32_t dwProductVersionLS; 119 | }; 120 | uint64_t qwProductVersion; 121 | }; 122 | uint32_t dwFileFlagsMask; 123 | uint32_t dwFileFlags; 124 | uint32_t dwFileOS; 125 | uint32_t dwFileType; 126 | uint32_t dwFileSubtype; 127 | union { 128 | struct { 129 | uint32_t dwFileDateMS; 130 | uint32_t dwFileDateLS; 131 | }; 132 | uint64_t qwFileDate; 133 | }; 134 | } cm_pe_version_t; 135 | 136 | typedef struct cm_pe_resource { 137 | uint32_t name; 138 | uint32_t offset; 139 | uint32_t file_offset; 140 | } cm_pe_res_t; 141 | #define CM_RES_REAL_SIZE 8 142 | 143 | typedef struct cm_pe_resdir { 144 | uint32_t characteristics; 145 | uint32_t timestamp; 146 | uint16_t major_version; 147 | uint16_t minor_version; 148 | uint16_t named_entry_count; 149 | uint16_t id_entry_count; 150 | 151 | size_t subdir_count; 152 | struct cm_pe_resdir* subdirs; 153 | size_t resource_count; 154 | cm_pe_res_t* resources; 155 | 156 | uint32_t offset; 157 | uint32_t name; 158 | } cm_pe_resdir_t; 159 | 160 | typedef struct cm_pe { 161 | FILE* f; 162 | cm_pe_header_t header; 163 | cm_pe_optional_header_t optional_header; 164 | cm_pe_windows_header_t windows_header; 165 | cm_pe_data_directory_t* data_directories; 166 | cm_pe_section_t* sections; 167 | } *cm_pe_t; 168 | 169 | #define IMAGE_FILE_MACHINE_UNKNOWN 0x0 170 | #define IMAGE_FILE_MACHINE_ALPHA 0x184 171 | #define IMAGE_FILE_MACHINE_ARM 0x1c0 172 | #define IMAGE_FILE_MACHINE_ALPHA64 0x284 173 | #define IMAGE_FILE_MACHINE_I386 0x14c 174 | #define IMAGE_FILE_MACHINE_IA64 0x200 175 | #define IMAGE_FILE_MACHINE_M68K 0x268 176 | #define IMAGE_FILE_MACHINE_MIPS16 0x266 177 | #define IMAGE_FILE_MACHINE_MIPSFPU 0x366 178 | #define IMAGE_FILE_MACHINE_MIPSFPU16 0x466 179 | #define IMAGE_FILE_MACHINE_POWERPC 0x1f0 180 | #define IMAGE_FILE_MACHINE_R3000 0x162 181 | #define IMAGE_FILE_MACHINE_R4000 0x166 182 | #define IMAGE_FILE_MACHINE_R10000 0x168 183 | #define IMAGE_FILE_MACHINE_SH3 0x1a2 184 | #define IMAGE_FILE_MACHINE_SH4 0x1a6 185 | #define IMAGE_FILE_MACHINE_THUMB 0x1c2 186 | 187 | MEXP(cm_pe_t) cm_pe_load(const char* filename); 188 | MEXP(void) cm_pe_unload(cm_pe_t pe); 189 | MEXP(cm_pe_resdir_t*) cm_pe_load_resources(cm_pe_t pe); 190 | MEXP(int) cm_pe_unload_resources(cm_pe_resdir_t* dir); 191 | MEXP(int) cm_pe_fixed_version(cm_pe_t pe, cm_pe_res_t* res, 192 | cm_pe_version_t* ver); 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif 197 | 198 | #endif 199 | -------------------------------------------------------------------------------- /src/bncsutil/sha1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sha1.c 3 | * 4 | * Description: 5 | * This file implements the Secure Hashing Algorithm 1 as 6 | * defined in FIPS PUB 180-1 published April 17, 1995. 7 | * 8 | * The SHA-1, produces a 160-bit message digest for a given 9 | * data stream. It should take about 2**n steps to find a 10 | * message with the same digest as a given message and 11 | * 2**(n/2) to find any two messages with the same digest, 12 | * when n is the digest size in bits. Therefore, this 13 | * algorithm can serve as a means of providing a 14 | * "fingerprint" for a message. 15 | * 16 | * Portability Issues: 17 | * SHA-1 is defined in terms of 32-bit "words". This code 18 | * uses (included via "sha1.h" to define 32 and 8 19 | * bit unsigned integer types. If your C compiler does not 20 | * support 32 bit unsigned integers, this code is not 21 | * appropriate. 22 | * 23 | * Caveats: 24 | * SHA-1 is designed to work with messages less than 2^64 bits 25 | * long. Although SHA-1 allows a message digest to be generated 26 | * for messages of any number of bits less than 2^64, this 27 | * implementation only works with messages with a length that is 28 | * a multiple of the size of an 8-bit character. 29 | * 30 | */ 31 | 32 | #include 33 | 34 | /* 35 | * Define the SHA1 circular left shift macro 36 | */ 37 | #define SHA1CircularShift(bits,word) \ 38 | (((word) << (bits)) | ((word) >> (32-(bits)))) 39 | 40 | /* Local Function Prototyptes */ 41 | void SHA1PadMessage(SHA1Context * /*context*/); 42 | void SHA1ProcessMessageBlock(SHA1Context * /*context*/); 43 | 44 | /* 45 | * SHA1Reset 46 | * 47 | * Description: 48 | * This function will initialize the SHA1Context in preparation 49 | * for computing a new SHA1 message digest. 50 | * 51 | * Parameters: 52 | * context: [in/out] 53 | * The context to reset. 54 | * 55 | * Returns: 56 | * sha Error Code. 57 | * 58 | */ 59 | int SHA1Reset(SHA1Context *context) 60 | { 61 | if (!context) 62 | { 63 | return shaNull; 64 | } 65 | 66 | context->Length_Low = 0; 67 | context->Length_High = 0; 68 | context->Message_Block_Index = 0; 69 | 70 | context->Intermediate_Hash[0] = 0x67452301; 71 | context->Intermediate_Hash[1] = 0xEFCDAB89; 72 | context->Intermediate_Hash[2] = 0x98BADCFE; 73 | context->Intermediate_Hash[3] = 0x10325476; 74 | context->Intermediate_Hash[4] = 0xC3D2E1F0; 75 | 76 | context->Computed = 0; 77 | context->Corrupted = 0; 78 | 79 | return shaSuccess; 80 | } 81 | 82 | /* 83 | * SHA1Result 84 | * 85 | * Description: 86 | * This function will return the 160-bit message digest into the 87 | * Message_Digest array provided by the caller. 88 | * NOTE: The first octet of hash is stored in the 0th element, 89 | * the last octet of hash in the 19th element. 90 | * 91 | * Parameters: 92 | * context: [in/out] 93 | * The context to use to calculate the SHA-1 hash. 94 | * Message_Digest: [out] 95 | * Where the digest is returned. 96 | * 97 | * Returns: 98 | * sha Error Code. 99 | * 100 | */ 101 | int SHA1Result( SHA1Context *context, 102 | uint8_t Message_Digest[SHA1HashSize]) 103 | { 104 | int i; 105 | 106 | if (!context || !Message_Digest) 107 | { 108 | return shaNull; 109 | } 110 | 111 | if (context->Corrupted) 112 | { 113 | return context->Corrupted; 114 | } 115 | 116 | if (!context->Computed) 117 | { 118 | SHA1PadMessage(context); 119 | for(i=0; i<64; ++i) 120 | { 121 | /* message may be sensitive, clear it out */ 122 | context->Message_Block[i] = 0; 123 | } 124 | context->Length_Low = 0; /* and clear length */ 125 | context->Length_High = 0; 126 | context->Computed = 1; 127 | 128 | } 129 | 130 | for(i = 0; i < SHA1HashSize; ++i) 131 | { 132 | Message_Digest[i] = context->Intermediate_Hash[i>>2] 133 | >> 8 * ( 3 - ( i & 0x03 ) ); 134 | } 135 | 136 | return shaSuccess; 137 | } 138 | 139 | /* 140 | * SHA1Input 141 | * 142 | * Description: 143 | * This function accepts an array of octets as the next portion 144 | * of the message. 145 | * 146 | * Parameters: 147 | * context: [in/out] 148 | * The SHA context to update 149 | * message_array: [in] 150 | * An array of characters representing the next portion of 151 | * the message. 152 | * length: [in] 153 | * The length of the message in message_array 154 | * 155 | * Returns: 156 | * sha Error Code. 157 | * 158 | */ 159 | int SHA1Input( SHA1Context *context, 160 | const uint8_t *message_array, 161 | unsigned length) 162 | { 163 | if (!length) 164 | { 165 | return shaSuccess; 166 | } 167 | 168 | if (!context || !message_array) 169 | { 170 | return shaNull; 171 | } 172 | 173 | if (context->Computed) 174 | { 175 | context->Corrupted = shaStateError; 176 | 177 | return shaStateError; 178 | } 179 | 180 | if (context->Corrupted) 181 | { 182 | return context->Corrupted; 183 | } 184 | while(length-- && !context->Corrupted) 185 | { 186 | context->Message_Block[context->Message_Block_Index++] = 187 | (*message_array & 0xFF); 188 | 189 | context->Length_Low += 8; 190 | if (context->Length_Low == 0) 191 | { 192 | context->Length_High++; 193 | if (context->Length_High == 0) 194 | { 195 | /* Message is too long */ 196 | context->Corrupted = 1; 197 | } 198 | } 199 | 200 | if (context->Message_Block_Index == 64) 201 | { 202 | SHA1ProcessMessageBlock(context); 203 | } 204 | 205 | message_array++; 206 | } 207 | 208 | return shaSuccess; 209 | } 210 | 211 | /* 212 | * SHA1ProcessMessageBlock 213 | * 214 | * Description: 215 | * This function will process the next 512 bits of the message 216 | * stored in the Message_Block array. 217 | * 218 | * Parameters: 219 | * None. 220 | * 221 | * Returns: 222 | * Nothing. 223 | * 224 | * Comments: 225 | 226 | * Many of the variable names in this code, especially the 227 | * single character names, were used because those were the 228 | * names used in the publication. 229 | * 230 | * 231 | */ 232 | void SHA1ProcessMessageBlock(SHA1Context *context) 233 | { 234 | const uint32_t K[] = { /* Constants defined in SHA-1 */ 235 | 0x5A827999, 236 | 0x6ED9EBA1, 237 | 0x8F1BBCDC, 238 | 0xCA62C1D6 239 | }; 240 | int t; /* Loop counter */ 241 | uint32_t temp; /* Temporary word value */ 242 | uint32_t W[80]; /* Word sequence */ 243 | uint32_t A, B, C, D, E; /* Word buffers */ 244 | 245 | /* 246 | * Initialize the first 16 words in the array W 247 | */ 248 | for(t = 0; t < 16; t++) 249 | { 250 | W[t] = context->Message_Block[t * 4] << 24; 251 | W[t] |= context->Message_Block[t * 4 + 1] << 16; 252 | W[t] |= context->Message_Block[t * 4 + 2] << 8; 253 | W[t] |= context->Message_Block[t * 4 + 3]; 254 | } 255 | 256 | for(t = 16; t < 80; t++) 257 | { 258 | W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 259 | } 260 | 261 | A = context->Intermediate_Hash[0]; 262 | B = context->Intermediate_Hash[1]; 263 | C = context->Intermediate_Hash[2]; 264 | D = context->Intermediate_Hash[3]; 265 | E = context->Intermediate_Hash[4]; 266 | 267 | for(t = 0; t < 20; t++) 268 | { 269 | temp = SHA1CircularShift(5,A) + 270 | ((B & C) | ((~B) & D)) + E + W[t] + K[0]; 271 | E = D; 272 | D = C; 273 | C = SHA1CircularShift(30,B); 274 | 275 | B = A; 276 | A = temp; 277 | } 278 | 279 | for(t = 20; t < 40; t++) 280 | { 281 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; 282 | E = D; 283 | D = C; 284 | C = SHA1CircularShift(30,B); 285 | B = A; 286 | A = temp; 287 | } 288 | 289 | for(t = 40; t < 60; t++) 290 | { 291 | temp = SHA1CircularShift(5,A) + 292 | ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; 293 | E = D; 294 | D = C; 295 | C = SHA1CircularShift(30,B); 296 | B = A; 297 | A = temp; 298 | } 299 | 300 | for(t = 60; t < 80; t++) 301 | { 302 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; 303 | E = D; 304 | D = C; 305 | C = SHA1CircularShift(30,B); 306 | B = A; 307 | A = temp; 308 | } 309 | 310 | context->Intermediate_Hash[0] += A; 311 | context->Intermediate_Hash[1] += B; 312 | context->Intermediate_Hash[2] += C; 313 | context->Intermediate_Hash[3] += D; 314 | context->Intermediate_Hash[4] += E; 315 | 316 | context->Message_Block_Index = 0; 317 | } 318 | 319 | /* 320 | * SHA1PadMessage 321 | * 322 | 323 | * Description: 324 | * According to the standard, the message must be padded to an even 325 | * 512 bits. The first padding bit must be a '1'. The last 64 326 | * bits represent the length of the original message. All bits in 327 | * between should be 0. This function will pad the message 328 | * according to those rules by filling the Message_Block array 329 | * accordingly. It will also call the ProcessMessageBlock function 330 | * provided appropriately. When it returns, it can be assumed that 331 | * the message digest has been computed. 332 | * 333 | * Parameters: 334 | * context: [in/out] 335 | * The context to pad 336 | * ProcessMessageBlock: [in] 337 | * The appropriate SHA*ProcessMessageBlock function 338 | * Returns: 339 | * Nothing. 340 | * 341 | */ 342 | 343 | void SHA1PadMessage(SHA1Context *context) 344 | { 345 | /* 346 | * Check to see if the current message block is too small to hold 347 | * the initial padding bits and length. If so, we will pad the 348 | * block, process it, and then continue padding into a second 349 | * block. 350 | */ 351 | if (context->Message_Block_Index > 55) 352 | { 353 | context->Message_Block[context->Message_Block_Index++] = 0x80; 354 | while(context->Message_Block_Index < 64) 355 | { 356 | context->Message_Block[context->Message_Block_Index++] = 0; 357 | } 358 | 359 | SHA1ProcessMessageBlock(context); 360 | 361 | while(context->Message_Block_Index < 56) 362 | { 363 | context->Message_Block[context->Message_Block_Index++] = 0; 364 | } 365 | } 366 | else 367 | { 368 | context->Message_Block[context->Message_Block_Index++] = 0x80; 369 | while(context->Message_Block_Index < 56) 370 | { 371 | 372 | context->Message_Block[context->Message_Block_Index++] = 0; 373 | } 374 | } 375 | 376 | /* 377 | * Store the message length as the last 8 octets 378 | */ 379 | context->Message_Block[56] = context->Length_High >> 24; 380 | context->Message_Block[57] = context->Length_High >> 16; 381 | context->Message_Block[58] = context->Length_High >> 8; 382 | context->Message_Block[59] = context->Length_High; 383 | context->Message_Block[60] = context->Length_Low >> 24; 384 | context->Message_Block[61] = context->Length_Low >> 16; 385 | context->Message_Block[62] = context->Length_Low >> 8; 386 | context->Message_Block[63] = context->Length_Low; 387 | 388 | SHA1ProcessMessageBlock(context); 389 | } 390 | -------------------------------------------------------------------------------- /src/bncsutil/sha1.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sha1.h 3 | * 4 | * Description: 5 | * This is the header file for code which implements the Secure 6 | * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published 7 | * April 17, 1995. 8 | * 9 | * Many of the variable names in this code, especially the 10 | * single character names, were used because those were the names 11 | * used in the publication. 12 | * 13 | * Please read the file sha1.c for more information. 14 | * 15 | */ 16 | 17 | #ifndef _SHA1_H_ 18 | #define _SHA1_H_ 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* 27 | * If you do not have the ISO standard stdint.h header file, then you 28 | * must typdef the following: 29 | * name meaning 30 | * uint32_t unsigned 32 bit integer 31 | * uint8_t unsigned 8 bit integer (i.e., unsigned char) 32 | * int_least16_t integer of >= 16 bits 33 | * 34 | */ 35 | 36 | #ifndef _SHA_enum_ 37 | #define _SHA_enum_ 38 | enum 39 | { 40 | shaSuccess = 0, 41 | shaNull, /* Null pointer parameter */ 42 | shaInputTooLong, /* input data too long */ 43 | shaStateError /* called Input after Result */ 44 | }; 45 | #endif 46 | #define SHA1HashSize 20 47 | 48 | /* 49 | * This structure will hold context information for the SHA-1 50 | * hashing operation 51 | */ 52 | typedef struct SHA1Context 53 | { 54 | uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ 55 | 56 | uint32_t Length_Low; /* Message length in bits */ 57 | uint32_t Length_High; /* Message length in bits */ 58 | 59 | /* Index into message block array */ 60 | int_least16_t Message_Block_Index; 61 | uint8_t Message_Block[64]; /* 512-bit message blocks */ 62 | 63 | int Computed; /* Is the digest computed? */ 64 | int Corrupted; /* Is the message digest corrupted? */ 65 | } SHA1Context; 66 | 67 | /* 68 | * Function Prototypes 69 | */ 70 | 71 | int SHA1Reset( SHA1Context *); 72 | int SHA1Input( SHA1Context *, 73 | const uint8_t *, 74 | unsigned int); 75 | int SHA1Result( SHA1Context *, 76 | uint8_t Message_Digest[SHA1HashSize]); 77 | 78 | #ifdef __cplusplus 79 | } // extern "C" 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/bncsutil/stack.c: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Stack 8 | * August 16, 2005 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | /** 27 | * Mule Server 28 | * Copyright (c) 2004-2006 Eric Naeseth. 29 | * 30 | * Stack 31 | * May 13, 2005 32 | */ 33 | 34 | #include 35 | #include 36 | 37 | cm_stack_t cm_stack_create() 38 | { 39 | cm_stack_t stack = (cm_stack_t) calloc(1, sizeof(struct cm_stack)); 40 | if (!stack) 41 | return (cm_stack_t) 0; 42 | return stack; 43 | } 44 | 45 | void cm_stack_destroy(cm_stack_t stack) 46 | { 47 | cm_stack_node_t* node; 48 | cm_stack_node_t* next; 49 | 50 | if (!stack) 51 | return; 52 | 53 | node = stack->top; 54 | 55 | while (node) { 56 | next = node->next; 57 | free(node); 58 | node = next; 59 | } 60 | 61 | free(stack); 62 | } 63 | 64 | void cm_stack_push(cm_stack_t stack, void* item) 65 | { 66 | cm_stack_node_t* new_node; 67 | 68 | if (!stack || !item) 69 | return; 70 | 71 | new_node = (cm_stack_node_t*) malloc(sizeof(cm_stack_node_t)); 72 | if (!new_node) 73 | return; 74 | new_node->next = stack->top; 75 | new_node->value = item; 76 | 77 | stack->size++; 78 | 79 | stack->top = new_node; 80 | } 81 | 82 | void* cm_stack_pop(cm_stack_t stack) 83 | { 84 | cm_stack_node_t* next; 85 | void* value; 86 | 87 | if (!stack || !stack->top) 88 | return (void*) 0; 89 | 90 | next = stack->top->next; 91 | value = stack->top->value; 92 | free(stack->top); 93 | 94 | stack->top = next; 95 | stack->size--; 96 | return value; 97 | } 98 | 99 | void* cm_stack_peek(cm_stack_t stack) 100 | { 101 | if (!stack || !stack->top) 102 | return (void*) 0; 103 | 104 | return stack->top->value; 105 | } 106 | 107 | unsigned int cm_stack_size(cm_stack_t stack) 108 | { 109 | if (!stack) 110 | return 0; 111 | 112 | return stack->size; 113 | } 114 | -------------------------------------------------------------------------------- /src/bncsutil/stack.h: -------------------------------------------------------------------------------- 1 | /** 2 | * BNCSutil 3 | * Battle.Net Utility Library 4 | * 5 | * Copyright (C) 2004-2006 Eric Naeseth 6 | * 7 | * Stack 8 | * August 16, 2005 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * A copy of the GNU Lesser General Public License is included in the BNCSutil 21 | * distribution in the file COPYING. If you did not receive this copy, 22 | * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 | * Boston, MA 02111-1307 USA 24 | */ 25 | 26 | /** 27 | * Mule Server 28 | * Copyright (c) 2004-2006 Eric Naeseth. 29 | * 30 | * Stack 31 | * May 13, 2005 32 | */ 33 | 34 | #ifndef CM_STACK_H_INCLUDED 35 | #define CM_STACK_H_INCLUDED 1 36 | 37 | typedef struct cm_stack_node { 38 | void* value; 39 | struct cm_stack_node* next; 40 | } cm_stack_node_t; 41 | 42 | typedef struct cm_stack { 43 | unsigned int size; 44 | cm_stack_node_t* top; 45 | } *cm_stack_t; 46 | 47 | cm_stack_t cm_stack_create(); 48 | void cm_stack_destroy(cm_stack_t stack); 49 | void cm_stack_push(cm_stack_t stack, void* item); 50 | void* cm_stack_pop(cm_stack_t stack); 51 | void* cm_stack_peek(cm_stack_t stack); 52 | unsigned int cm_stack_size(cm_stack_t stack); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /vb6_example/.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-vendored=true 2 | -------------------------------------------------------------------------------- /vb6_example/BNCSutil.bas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BNETDocs/bncsutil/2993cefdaf87acc29b06cb9c1620de74f94cfd7f/vb6_example/BNCSutil.bas -------------------------------------------------------------------------------- /vb6_example/BNCSutilExample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BNETDocs/bncsutil/2993cefdaf87acc29b06cb9c1620de74f94cfd7f/vb6_example/BNCSutilExample.exe -------------------------------------------------------------------------------- /vb6_example/BNCSutilExample.vbp: -------------------------------------------------------------------------------- 1 | Type=Exe 2 | Form=frmMain.frm 3 | Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\WINDOWS\system32\STDOLE2.TLB#OLE Automation 4 | Object={248DD890-BB45-11CF-9ABC-0080C7E7B78D}#1.0#0; MSWINSCK.OCX 5 | Module=Connection; Connection.bas 6 | Module=Interface; Interface.bas 7 | Module=BNCSutil; BNCSutil.bas 8 | Class=Packet; Packet.cls 9 | Form=frmNewAccount.frm 10 | IconForm="frmMain" 11 | Startup="frmMain" 12 | HelpFile="" 13 | Title="BNCSutilExample" 14 | ExeName32="BNCSutilExample.exe" 15 | Command32="" 16 | Name="BNCSutilExample" 17 | HelpContextID="0" 18 | CompatibleMode="0" 19 | MajorVer=1 20 | MinorVer=1 21 | RevisionVer=0 22 | AutoIncrementVer=0 23 | ServerSupportFiles=0 24 | VersionComments="BNCSutil Example Bot" 25 | VersionCompanyName="Cloaked" 26 | VersionFileDescription="BNCSutil Example Bot" 27 | VersionLegalCopyright="Placed in the public domain." 28 | VersionProductName="BNCSutil Example Bot" 29 | CompilationType=-1 30 | OptimizationType=0 31 | FavorPentiumPro(tm)=0 32 | CodeViewDebugInfo=0 33 | NoAliasing=0 34 | BoundsCheck=0 35 | OverflowCheck=0 36 | FlPointCheck=0 37 | FDIVCheck=0 38 | UnroundedFP=0 39 | StartMode=0 40 | Unattended=0 41 | Retained=0 42 | ThreadPerObject=0 43 | MaxNumberOfThreads=1 44 | 45 | [MS Transaction Server] 46 | AutoRefresh=1 47 | -------------------------------------------------------------------------------- /vb6_example/BNCSutilExample.vbw: -------------------------------------------------------------------------------- 1 | frmMain = 270, 18, 832, 605, Z, 0, 3, 414, 564, C 2 | Connection = 110, 120, 896, 520, 3 | Interface = 176, 192, 962, 592, 4 | BNCSutil = 22, 24, 808, 424, 5 | Packet = 0, 0, 786, 400, 6 | frmNewAccount = 110, 120, 896, 520, , 88, 96, 874, 496, C 7 | -------------------------------------------------------------------------------- /vb6_example/Interface.bas: -------------------------------------------------------------------------------- 1 | Attribute VB_Name = "Interface" 2 | Option Explicit 3 | 4 | '------------------------------------------------- 5 | ' Status Types 6 | '------------------------------------------------- 7 | Public Enum StatusTypes 8 | stNormal = 0 9 | stError 10 | End Enum 11 | 12 | '------------------------------------------------- 13 | ' Folder Browsing API Declarations 14 | '------------------------------------------------- 15 | Private Type BrowseInfo 16 | hWndOwner As Long 17 | pidlRoot As Long 18 | sDisplayName As String 19 | sTitle As String 20 | ulFlags As Long 21 | lpfn As Long 22 | lParam As Long 23 | iImage As Long 24 | End Type 25 | 26 | Private Declare Function SHBrowseForFolder Lib "Shell32.dll" (bBrowse As BrowseInfo) As Long 27 | Private Declare Function SHGetPathFromIDList Lib "Shell32.dll" (ByVal lItem As Long, ByVal sDir As String) As Long 28 | 29 | 30 | '------------------------------------------------- 31 | ' Update Status 32 | '------------------------------------------------- 33 | Public Sub UpdateStatus(NewStatus As String, Optional ByVal sType As StatusTypes = stNormal) 34 | frmMain.lblStatus.Caption = NewStatus 35 | 36 | Select Case sType 37 | Case stNormal 38 | frmMain.lblStatus.ForeColor = vbButtonText 39 | Case stError 40 | frmMain.lblStatus.ForeColor = vbRed 41 | End Select 42 | End Sub 43 | 44 | '------------------------------------------------- 45 | ' Configuration Verifier 46 | '------------------------------------------------- 47 | ' Checks the fields on the form to make sure 48 | ' they have all been filled in properly. 49 | '------------------------------------------------- 50 | Public Function VerifyConfig() As Boolean 51 | VerifyConfig = False 52 | 53 | With frmMain 54 | If (.WS.State = sckConnected Or .WS.State = sckConnecting) Then 55 | Disconnect 56 | End If 57 | 58 | .cmdConnect.Enabled = False 59 | 60 | ' First, determine whether to enable 61 | ' the expansion CD-key field. 62 | If (KeyCount(GetClient()) = 2) Then 63 | .txtCDKey(1).Locked = False 64 | .txtCDKey(1).BackColor = vbWindowBackground 65 | .txtCDKey(1).ForeColor = vbWindowText 66 | Else 67 | .txtCDKey(1).Locked = True 68 | .txtCDKey(1).BackColor = vbButtonFace 69 | .txtCDKey(1).ForeColor = vbGrayText 70 | End If 71 | 72 | ' Check the config fields to see if something 73 | ' has been entered. 74 | 75 | If LenB(.txtUsername.Text) = 0 Then 76 | UpdateStatus "You must enter a username.", stError 77 | Exit Function 78 | End If 79 | 80 | If LenB(.txtPassword.Text) = 0 Then 81 | UpdateStatus "You must enter a password.", stError 82 | Exit Function 83 | End If 84 | 85 | If LenB(.txtCDKey(0).Text) = 0 Then 86 | UpdateStatus "You must enter a CD-key.", stError 87 | Exit Function 88 | End If 89 | 90 | If .txtCDKey(1).Locked = False And LenB(.txtCDKey(1).Text) = 0 Then 91 | UpdateStatus "You must enter an expansion CD-key.", stError 92 | Exit Function 93 | End If 94 | 95 | If LenB(.txtServer.Text) = 0 Then 96 | UpdateStatus "You must enter a server.", stError 97 | Exit Function 98 | End If 99 | 100 | If GetClient() = UNKN Then 101 | UpdateStatus "You must pick a client.", stError 102 | Exit Function 103 | End If 104 | 105 | If LenB(.txtHashFolder.Text) = 0 Then 106 | UpdateStatus "You must enter a hash folder.", stError 107 | Exit Function 108 | End If 109 | 110 | If .chkChangePassword.Value = vbChecked Then 111 | If LenB(.txtNewPassword.Text) = 0 Then 112 | UpdateStatus "You must enter a new password.", stError 113 | Exit Function 114 | End If 115 | 116 | If LenB(.txtNewPassword2.Text) = 0 Then 117 | UpdateStatus "You must confirm your password.", stError 118 | Exit Function 119 | End If 120 | 121 | If (.txtNewPassword.Text <> .txtNewPassword2.Text) Then 122 | UpdateStatus "The new password and its confirmation do not match.", stError 123 | Exit Function 124 | End If 125 | End If 126 | 127 | ' OK 128 | UpdateStatus "Ready to connect." 129 | .cmdConnect.Enabled = True 130 | VerifyConfig = True 131 | 132 | End With 133 | End Function 134 | 135 | '------------------------------------------------- 136 | ' Get Client Code 137 | '------------------------------------------------- 138 | ' Returns the Battle.Net product code (e.g. SEXP) 139 | ' for the client chosen on the form. 140 | '------------------------------------------------- 141 | Public Function GetClient() As BNCSProducts 142 | GetClient = frmMain.Product 143 | End Function 144 | 145 | '------------------------------------------------- 146 | ' Folder Browsing 147 | '------------------------------------------------- 148 | ' Let the user browse for a folder. Returns the 149 | ' selected folder or vbNullString on cancel. 150 | '------------------------------------------------- 151 | Public Function BrowseForFolder() As String 152 | Dim browse_info As BrowseInfo 153 | Dim item As Long 154 | Dim dir_name As String 155 | 156 | BrowseForFolder = vbNullString 157 | 158 | browse_info.hWndOwner = frmMain.hWnd 159 | browse_info.pidlRoot = 0 160 | browse_info.sDisplayName = String$(260, vbNullChar) 161 | browse_info.sTitle = "Select Hash Directory" 162 | browse_info.ulFlags = 1 ' Return directory name. 163 | browse_info.lpfn = 0 164 | browse_info.lParam = 0 165 | browse_info.iImage = 0 166 | 167 | item = SHBrowseForFolder(browse_info) 168 | If item Then 169 | dir_name = String$(260, vbNullChar) 170 | If SHGetPathFromIDList(item, dir_name) Then 171 | BrowseForFolder = Left(dir_name, InStr(dir_name, Chr$(0)) - 1) 172 | Else 173 | BrowseForFolder = vbNullString 174 | End If 175 | End If 176 | End Function 177 | 178 | '------------------------------------------------- 179 | ' Ask to Create Account 180 | '------------------------------------------------- 181 | Public Sub ShowAccountCreate() 182 | frmNewAccount.Show 183 | End Sub 184 | -------------------------------------------------------------------------------- /vb6_example/MSSCCPRJ.SCC: -------------------------------------------------------------------------------- 1 | [SCC] 2 | SCC=This is a source code control file 3 | [BNCSutilExample.vbp] 4 | SCC_Project_Name=this project is not under source code control 5 | SCC_Aux_Path= 6 | -------------------------------------------------------------------------------- /vb6_example/NLS.cls: -------------------------------------------------------------------------------- 1 | VERSION 1.0 CLASS 2 | BEGIN 3 | MultiUse = -1 'True 4 | Persistable = 0 'NotPersistable 5 | DataBindingBehavior = 0 'vbNone 6 | DataSourceBehavior = 0 'vbNone 7 | MTSTransactionMode = 0 'NotAnMTSObject 8 | END 9 | Attribute VB_Name = "NLS" 10 | Attribute VB_GlobalNameSpace = False 11 | Attribute VB_Creatable = False 12 | Attribute VB_PredeclaredId = False 13 | Attribute VB_Exposed = False 14 | Attribute VB_Ext_KEY = "SavedWithClassBuilder6" ,"Yes" 15 | Attribute VB_Ext_KEY = "Top_Level" ,"Yes" 16 | Option Explicit 17 | 18 | ' NLS Wrapper Class 19 | 20 | Private m_Username As String 21 | Private m_Password As String 22 | Private m_NLS As Long 23 | 24 | Private m_ServerKey As String 25 | Private m_Salt As String 26 | 27 | Private Sub Class_Terminate() 28 | On Error GoTo Trap 29 | If (m_NLS) Then _ 30 | nls_free m_NLS 31 | Trap: 32 | End Sub 33 | 34 | Public Property Get Username() As String 35 | Username = m_Username 36 | End Property 37 | 38 | Public Property Let Username(NewValue As String) 39 | m_Username = NewValue 40 | End Property 41 | 42 | Public Property Get Password() As String 43 | Password = m_Password 44 | End Property 45 | 46 | Public Property Let Password(NewValue As String) 47 | m_Password = NewValue 48 | End Property 49 | 50 | Public Property Get ServerKey() As String 51 | ServerKey = m_ServerKey 52 | End Property 53 | 54 | Public Property Let ServerKey(NewValue As String) 55 | m_ServerKey = NewValue 56 | End Property 57 | 58 | Public Property Get Salt() As String 59 | Salt = m_Salt 60 | End Property 61 | 62 | Public Property Let Salt(NewValue As String) 63 | m_Salt = NewValue 64 | End Property 65 | 66 | Public Property Get Handle() As Long 67 | If (m_NLS = 0 And LenB(m_Username) > 0 And LenB(m_Password) > 0) Then 68 | m_NLS = nls_init(m_Username, m_Password) 69 | End If 70 | Handle = m_NLS 71 | End Property 72 | 73 | Public Property Let Handle(ByVal NewValue As Long) 74 | If (m_NLS) Then _ 75 | nls_free m_NLS 76 | m_NLS = NewValue 77 | End Property 78 | 79 | Public Property Get PublicKey() As String 80 | PublicKey = String$(32, vbNullChar) 81 | nls_get_A Handle, PublicKey 82 | End Property 83 | 84 | Public Property Get ClientPasswordProof() As String 85 | ClientPasswordProof = String$(20, vbNullChar) 86 | nls_get_M1 Handle, ClientPasswordProof, m_ServerKey, m_Salt 87 | End Property 88 | 89 | Public Function VerifyServerProof(ServerProof As String) As Boolean 90 | If (nls_check_M2(Handle, ServerProof, vbNullString, vbNullString)) Then 91 | VerifyServerProof = True 92 | Else 93 | VerifyServerProof = False 94 | End If 95 | End Function 96 | 97 | Public Property Get CreateAccount() As Buffer 98 | Dim CreateBuf As String, DataLen As Long 99 | 100 | DataLen = Len(m_Username) + 65 101 | CreateBuf = String$(DataLen, vbNullChar) 102 | Set CreateAccount = New Buffer 103 | With CreateAccount 104 | nls_account_create Handle, CreateBuf, DataLen 105 | .AddRaw CreateBuf 106 | End With 107 | End Property 108 | -------------------------------------------------------------------------------- /vb6_example/Packet.cls: -------------------------------------------------------------------------------- 1 | VERSION 1.0 CLASS 2 | BEGIN 3 | MultiUse = -1 'True 4 | Persistable = 0 'NotPersistable 5 | DataBindingBehavior = 0 'vbNone 6 | DataSourceBehavior = 0 'vbNone 7 | MTSTransactionMode = 0 'NotAnMTSObject 8 | END 9 | Attribute VB_Name = "Packet" 10 | Attribute VB_GlobalNameSpace = False 11 | Attribute VB_Creatable = True 12 | Attribute VB_PredeclaredId = False 13 | Attribute VB_Exposed = False 14 | Option Explicit 15 | Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ 16 | (ByRef Destination As Any, ByRef Source As Any, ByVal numbytes As Long) 17 | 18 | Private Enum PacketType 19 | pIncoming 20 | pOutgoing 21 | pNull 22 | End Enum 23 | 24 | Public Enum PacketFormat 25 | pBnet 26 | pBNLS 27 | pMCP 28 | pNone 29 | pMatrix 30 | End Enum 31 | 32 | Private Const EOP_ERROR& = vbObjectError + 1201 33 | 34 | Private RawData As String 35 | Private Mode As PacketType 36 | Public Position As Long 37 | Public RaiseOverflowErrors As Boolean 38 | Private Const RAISE_OVERFLOW_ERRORS_DEFAULT As Boolean = False 39 | 40 | Public Property Get EOPError() As Long 41 | EOPError = EOP_ERROR 42 | End Property 43 | 44 | Public Sub Reset() 45 | Mode = pNull 46 | RawData = "" 47 | Position = 1 48 | End Sub 49 | 50 | Public Function SetData(Data As String) 51 | RawData = Data 52 | Mode = pIncoming 53 | End Function 54 | 55 | Public Function GetData() As String 56 | GetData = RawData 57 | Reset 58 | End Function 59 | 60 | Public Sub Skip(Bytes As Long) 61 | Position = Position + Bytes 62 | End Sub 63 | 64 | Public Function GetString() As String 65 | Dim NTPos&, strTemp$ 66 | GetString = "" 67 | NTPos = InStr(Position, RawData, vbNullChar) 68 | If NTPos = 0 Then 69 | If RaiseOverflowErrors Then _ 70 | Err.Raise EOP_ERROR, , "Trying to read past end of packet." 71 | Exit Function 72 | End If 73 | GetString = Mid$(RawData, Position, NTPos - Position) 74 | Position = NTPos + 1 75 | End Function 76 | 77 | Public Function GetFixedString(Length As Long) As String 78 | Dim rVal& 79 | If LenData() - Position + 1 >= Length Then 80 | GetFixedString = Mid$(RawData, Position, Length) 81 | Position = Position + Length 82 | Else 83 | If RaiseOverflowErrors Then _ 84 | Err.Raise EOP_ERROR, , "Trying to read past end of packet." 85 | Exit Function 86 | End If 87 | End Function 88 | 89 | Public Function GetBoolean(Optional ByVal Bytes As Long = 4) As Boolean 90 | Dim rVal& 91 | If LenData() - Position + 1 >= Bytes Then 92 | CopyMemory rVal, ByVal Mid$(RawData, Position, Bytes), Bytes 93 | Position = Position + Bytes 94 | Else 95 | If RaiseOverflowErrors Then _ 96 | Err.Raise EOP_ERROR, , "Trying to read past end of packet." 97 | Exit Function 98 | End If 99 | If rVal = 0 Then 100 | GetBoolean = False 101 | Else 102 | GetBoolean = True 103 | End If 104 | End Function 105 | 106 | Public Function GetDWORD() As Long 107 | Dim rVal& 108 | If LenData() - Position + 1 >= 4 Then 109 | CopyMemory rVal, ByVal Mid$(RawData, Position, 4), 4 110 | Position = Position + 4 111 | GetDWORD = rVal 112 | 'BotEvent "", evDbg, Position & ":" & StrToHex(Mid$(RawData, Position)) 113 | Else 114 | If RaiseOverflowErrors Then _ 115 | Err.Raise EOP_ERROR, , "Trying to read past end of packet." 116 | Exit Function 117 | End If 118 | End Function 119 | 120 | Public Function GetDWORDArray(Length As Long) As Long() 121 | If Length = 0 Then Exit Function 122 | Dim oS() As Long, i& 123 | ReDim oS(Length) As Long 124 | For i = 0 To Length - 1 125 | oS(i) = GetDWORD() 126 | Next i 127 | GetDWORDArray = oS 128 | End Function 129 | 130 | Public Function GetWORD() As Integer 131 | Dim rVal% 132 | If LenData() - Position + 1 >= 2 Then 133 | CopyMemory rVal, ByVal Mid$(RawData, Position, 2), 2 134 | Position = Position + 2 135 | GetWORD = rVal 136 | Else 137 | If RaiseOverflowErrors Then _ 138 | Err.Raise EOP_ERROR, , "Trying to read past end of packet." 139 | Exit Function 140 | End If 141 | End Function 142 | 143 | Public Function GetWORDArray(Length As Long) As Integer() 144 | If Length = 0 Then Exit Function 145 | Dim oS() As Integer, i& 146 | ReDim oS(Length) As Integer 147 | For i = 0 To Length - 1 148 | oS(i) = GetWORD() 149 | Next i 150 | GetWORDArray = oS 151 | End Function 152 | 153 | Public Function GetByte() As Byte 154 | Dim rVal As Byte 155 | rVal = 0 156 | If LenData() - Position + 1 >= 1 Then 157 | CopyMemory rVal, ByVal Mid$(RawData, Position, 1), 1 158 | Position = Position + 1 159 | GetByte = rVal 160 | Else 161 | If RaiseOverflowErrors Then _ 162 | Err.Raise EOP_ERROR, , "Trying to read past end of packet." 163 | GetByte = 0 164 | End If 165 | End Function 166 | 167 | Public Function GetStringArray(ByVal Length As Long) As String() 168 | If Length = 0 Then Exit Function 169 | Dim oS() As String, i& 170 | ReDim oS(Length) As String 171 | For i = 0 To Length - 1 172 | oS(i) = GetString() 173 | Next i 174 | GetStringArray = oS 175 | End Function 176 | 177 | Public Function LenData() As Long 178 | LenData = Len(RawData) 179 | End Function 180 | 181 | 'Used with Winsock.bas 182 | 'Public Function Send(Socket As Long, Optional PacketID As Byte, Optional ByVal Format As PacketFormat = pBnet) 183 | ' If Mode = pIncoming Then Exit Function 184 | ' Select Case Format 185 | ' Case pBnet 186 | ' SendData Socket, Chr$(&HFF) & MakeByte(PacketID) & _ 187 | ' MakeWORD(Len(RawData) + 4) & RawData 188 | ' Case pBNLS 189 | ' SendData Socket, MakeWORD(Len(RawData) + 3) & MakeByte(PacketID) & RawData 190 | ' Case pMCP 191 | ' SendData Socket, MakeWORD(Len(RawData) + 3) & MakeByte(PacketID) & RawData 192 | ' Case Else 193 | ' SendData Socket, RawData 194 | ' End Select 195 | ' Reset 196 | 'End Function 197 | 198 | Private Function HexByte(ByVal Number As Long) As String 199 | HexByte = Hex$(Number And &HFF) 200 | If Len(HexByte) = 1 Then _ 201 | HexByte = "0" & HexByte 202 | End Function 203 | 204 | 'Used with Winsock controls 205 | Public Sub Send(Socket As Winsock, Optional ByVal PacketID As Byte, Optional ByVal Format As PacketFormat = pBnet) 206 | On Error GoTo Trap 207 | Dim Data As String 208 | 209 | If Mode = pIncoming Then Exit Sub 210 | Select Case Format 211 | Case pBnet 212 | Data = Chr$(&HFF) & Chr$(PacketID) & _ 213 | MakeWORD(Len(RawData) + 4) & RawData 214 | Case pBNLS, pMCP 215 | Data = MakeWORD(Len(RawData) + 3) & Chr$(PacketID) & RawData 216 | Case pMatrix 217 | Data = MakeByte(PacketID) & Chr$(Len(RawData) + 3) & RawData 218 | Case Else 219 | Data = RawData 220 | End Select 221 | 222 | BNCSutil.DebugMessage "Outgoing Packet 0x" & HexByte(PacketID) & " (Length = " & Len(Data) & ")" 223 | BNCSutil.DebugHexDump Data 224 | 225 | Socket.SendData Data 226 | Reset 227 | Exit Sub 228 | Trap: 229 | On Error GoTo Trap2 230 | Disconnect 231 | Trap2: 232 | End Sub 233 | 234 | Public Sub InsertString(Data As String) 235 | If Mode = pIncoming Then Exit Sub 236 | Mode = pOutgoing 237 | RawData = RawData & Data & Chr$(0) 238 | End Sub 239 | 240 | Public Sub InsertStringList(Data() As String) 241 | 'On Error Resume Next 242 | If Mode = pIncoming Then Exit Sub 243 | Mode = pOutgoing 244 | Dim i As Integer 245 | For i = LBound(Data) To UBound(Data) Step 1 246 | RawData = RawData & Data(i) & Chr$(0) 247 | Next i 248 | RawData = RawData & Chr$(0) 'extra null byte to end stringlist 249 | End Sub 250 | 251 | Public Sub InsertStringArray(Data() As String) 252 | 'On Error Resume Next 253 | If Mode = pIncoming Then Exit Sub 254 | Mode = pOutgoing 255 | Dim i As Integer 256 | For i = LBound(Data) To UBound(Data) Step 1 257 | RawData = RawData & Data(i) & Chr$(0) 258 | Next i 259 | 'no extra null byte in string arrays 260 | End Sub 261 | 262 | Public Sub InsertNTString(Data As String) 263 | InsertString Data 264 | End Sub 265 | 266 | Public Sub InsertNonNTString(Data As String) 267 | If Mode = pIncoming Then Exit Sub 268 | Mode = pOutgoing 269 | RawData = RawData & Data 270 | End Sub 271 | 272 | Public Sub InsertByte(Data As Byte) 273 | If Mode = pIncoming Then Exit Sub 274 | Mode = pOutgoing 275 | 276 | RawData = RawData & MakeByte(Data) 277 | End Sub 278 | 279 | Public Sub InsertWORD(Data As Integer) 280 | If Mode = pIncoming Then Exit Sub 281 | Mode = pOutgoing 282 | 283 | RawData = RawData & MakeWORD(Data) 284 | End Sub 285 | 286 | Public Sub InsertDWORD(Data As Long) 287 | If Mode = pIncoming Then Exit Sub 288 | Mode = pOutgoing 289 | 290 | RawData = RawData & MakeDWORD(Data) 291 | End Sub 292 | 293 | Public Sub InsertDWORDArray(Data() As Long) 294 | If Mode = pIncoming Then Exit Sub 295 | Mode = pOutgoing 296 | 297 | Dim i As Integer 298 | For i = LBound(Data) To UBound(Data) Step 1 299 | RawData = RawData & MakeDWORD(Data(i)) 300 | Next i 301 | End Sub 302 | 303 | Private Function MakeByte(Data As Byte) As String 304 | Dim Result As String * 1 305 | CopyMemory ByVal Result, Data, 1 306 | MakeByte = Result 307 | End Function 308 | 309 | Private Function MakeWORD(Data As Integer) As String 310 | Dim Result As String * 2 311 | CopyMemory ByVal Result, Data, 2 312 | MakeWORD = Result 313 | End Function 314 | 315 | Public Function MakeDWORD(Data As Long) As String 316 | Dim Result As String * 4 317 | CopyMemory ByVal Result, Data, 4 318 | MakeDWORD = Result 319 | End Function 320 | 321 | Private Sub Class_Initialize() 322 | Position = 1 323 | Mode = pNull 324 | RaiseOverflowErrors = RAISE_OVERFLOW_ERRORS_DEFAULT 325 | End Sub 326 | -------------------------------------------------------------------------------- /vb6_example/frmMain.frm: -------------------------------------------------------------------------------- 1 | VERSION 5.00 2 | Object = "{248DD890-BB45-11CF-9ABC-0080C7E7B78D}#1.0#0"; "MSWINSCK.OCX" 3 | Begin VB.Form frmMain 4 | BorderStyle = 1 'Fixed Single 5 | Caption = "BNCSutil Example" 6 | ClientHeight = 6330 7 | ClientLeft = 45 8 | ClientTop = 360 9 | ClientWidth = 5070 10 | BeginProperty Font 11 | Name = "Tahoma" 12 | Size = 8.25 13 | Charset = 0 14 | Weight = 400 15 | Underline = 0 'False 16 | Italic = 0 'False 17 | Strikethrough = 0 'False 18 | EndProperty 19 | LinkTopic = "Form1" 20 | MaxButton = 0 'False 21 | ScaleHeight = 6330 22 | ScaleWidth = 5070 23 | StartUpPosition = 3 'Windows Default 24 | Begin VB.Frame fraStatus 25 | Caption = "Status" 26 | Height = 855 27 | Left = 120 28 | TabIndex = 20 29 | Top = 4200 30 | Width = 4815 31 | Begin VB.Label lblStatus 32 | Alignment = 2 'Center 33 | Height = 255 34 | Left = 120 35 | TabIndex = 21 36 | Top = 360 37 | Width = 4575 38 | End 39 | End 40 | Begin VB.Frame fraConfig 41 | Caption = "Configuration" 42 | Height = 3375 43 | Left = 120 44 | TabIndex = 4 45 | Top = 600 46 | Width = 4815 47 | Begin VB.TextBox txtNewPassword2 48 | Height = 285 49 | IMEMode = 3 'DISABLE 50 | Left = 1440 51 | PasswordChar = "*" 52 | TabIndex = 25 53 | Top = 3720 54 | Width = 2535 55 | End 56 | Begin VB.TextBox txtNewPassword 57 | Height = 285 58 | IMEMode = 3 'DISABLE 59 | Left = 1440 60 | PasswordChar = "*" 61 | TabIndex = 23 62 | Top = 3360 63 | Width = 2535 64 | End 65 | Begin VB.CheckBox chkChangePassword 66 | Caption = "Change password when connected." 67 | Height = 255 68 | Left = 120 69 | TabIndex = 22 70 | Top = 3000 71 | Width = 3735 72 | End 73 | Begin VB.CommandButton cmdBrowseHashes 74 | Caption = "Browse" 75 | Height = 255 76 | Left = 3960 77 | TabIndex = 19 78 | Top = 2520 79 | Width = 735 80 | End 81 | Begin VB.TextBox txtHashFolder 82 | Height = 285 83 | Left = 1320 84 | TabIndex = 18 85 | Top = 2520 86 | Width = 2535 87 | End 88 | Begin VB.TextBox txtServer 89 | Height = 285 90 | Left = 1320 91 | TabIndex = 14 92 | Top = 1800 93 | Width = 2535 94 | End 95 | Begin VB.ComboBox cmbClient 96 | Height = 315 97 | Left = 1320 98 | Style = 2 'Dropdown List 99 | TabIndex = 16 100 | Top = 2160 101 | Width = 2535 102 | End 103 | Begin VB.TextBox txtCDKey 104 | Height = 285 105 | Index = 1 106 | Left = 1320 107 | TabIndex = 12 108 | Top = 1440 109 | Width = 2535 110 | End 111 | Begin VB.TextBox txtCDKey 112 | Height = 285 113 | Index = 0 114 | Left = 1320 115 | TabIndex = 10 116 | Top = 1080 117 | Width = 2535 118 | End 119 | Begin VB.TextBox txtPassword 120 | Height = 285 121 | IMEMode = 3 'DISABLE 122 | Left = 1320 123 | PasswordChar = "*" 124 | TabIndex = 8 125 | Top = 720 126 | Width = 2535 127 | End 128 | Begin VB.TextBox txtUsername 129 | Height = 285 130 | Left = 1320 131 | TabIndex = 6 132 | Top = 360 133 | Width = 2535 134 | End 135 | Begin VB.Label lblNewPassword2 136 | Caption = "Confirm:" 137 | Height = 255 138 | Left = 120 139 | TabIndex = 26 140 | Top = 3750 141 | Width = 975 142 | End 143 | Begin VB.Label lblNewPassword 144 | Caption = "New Password:" 145 | Height = 255 146 | Left = 120 147 | TabIndex = 24 148 | Top = 3390 149 | Width = 1215 150 | End 151 | Begin VB.Label Label9 152 | Caption = "Hash Folder:" 153 | Height = 255 154 | Left = 120 155 | TabIndex = 17 156 | Top = 2550 157 | Width = 975 158 | End 159 | Begin VB.Label Label8 160 | Caption = "Server:" 161 | Height = 255 162 | Left = 120 163 | TabIndex = 13 164 | Top = 1830 165 | Width = 975 166 | End 167 | Begin VB.Label Label7 168 | Caption = "Client:" 169 | Height = 255 170 | Left = 120 171 | TabIndex = 15 172 | Top = 2220 173 | Width = 975 174 | End 175 | Begin VB.Label Label5 176 | Caption = "Expansion Key:" 177 | Height = 255 178 | Left = 120 179 | TabIndex = 11 180 | Top = 1470 181 | Width = 1215 182 | End 183 | Begin VB.Label Label4 184 | Caption = "CD-Key:" 185 | Height = 255 186 | Left = 120 187 | TabIndex = 9 188 | Top = 1110 189 | Width = 975 190 | End 191 | Begin VB.Label Label3 192 | Caption = "Password:" 193 | Height = 255 194 | Left = 120 195 | TabIndex = 7 196 | Top = 750 197 | Width = 975 198 | End 199 | Begin VB.Label Label2 200 | Caption = "Username:" 201 | Height = 255 202 | Left = 120 203 | TabIndex = 5 204 | Top = 390 205 | Width = 975 206 | End 207 | End 208 | Begin VB.Frame fraButtons 209 | Height = 1095 210 | Left = 0 211 | TabIndex = 1 212 | Top = 5280 213 | Width = 8775 214 | Begin VB.CheckBox chkDebug 215 | Caption = "Show BNCSutil debug messages." 216 | Height = 255 217 | Left = 120 218 | TabIndex = 27 219 | Top = 720 220 | Width = 2775 221 | End 222 | Begin MSWinsockLib.Winsock WS 223 | Left = 2280 224 | Top = 240 225 | _ExtentX = 741 226 | _ExtentY = 741 227 | _Version = 393216 228 | End 229 | Begin VB.CommandButton cmdConnect 230 | Caption = "Connect" 231 | Height = 375 232 | Left = 120 233 | TabIndex = 3 234 | Top = 240 235 | Width = 1215 236 | End 237 | Begin VB.CommandButton cmdExit 238 | Caption = "Exit" 239 | Height = 375 240 | Left = 3720 241 | TabIndex = 2 242 | Top = 240 243 | Width = 1215 244 | End 245 | End 246 | Begin VB.Label Label1 247 | Caption = "A simple example of how to connect to Battle.Net using BNCSutil." 248 | Height = 255 249 | Left = 120 250 | TabIndex = 0 251 | Top = 120 252 | Width = 6135 253 | End 254 | End 255 | Attribute VB_Name = "frmMain" 256 | Attribute VB_GlobalNameSpace = False 257 | Attribute VB_Creatable = False 258 | Attribute VB_PredeclaredId = True 259 | Attribute VB_Exposed = False 260 | Option Explicit 261 | 262 | Private ProductMap() As BNCSProducts 263 | Public Product As BNCSProducts 264 | 265 | Private Sub chkChangePassword_Click() 266 | If chkChangePassword.Value Then 267 | Height = 7605 268 | fraConfig.Height = 4215 269 | fraStatus.Top = 5040 270 | fraButtons.Top = 6120 271 | lblNewPassword.Visible = True 272 | lblNewPassword2.Visible = True 273 | txtNewPassword.Visible = True 274 | txtNewPassword2.Visible = True 275 | Else 276 | Height = 6765 277 | fraConfig.Height = 3375 278 | fraStatus.Top = 4200 279 | fraButtons.Top = 5280 280 | lblNewPassword.Visible = False 281 | lblNewPassword2.Visible = False 282 | txtNewPassword.Visible = False 283 | txtNewPassword2.Visible = False 284 | End If 285 | VerifyConfig 286 | End Sub 287 | 288 | Private Sub cmbChange() 289 | VerifyConfig 290 | End Sub 291 | 292 | Private Sub cmbClick() 293 | VerifyConfig 294 | End Sub 295 | 296 | Private Sub chkDebug_Click() 297 | BNCSutil.DebugMode = (chkDebug.Value = vbChecked) 298 | End Sub 299 | 300 | Private Sub cmbClient_Change() 301 | Dim Index As Long 302 | 303 | Index = cmbClient.ListIndex 304 | 305 | If Index < LBound(ProductMap) Or Index > UBound(ProductMap) Then 306 | ' sanity check 307 | Product = UNKN 308 | Exit Sub 309 | End If 310 | 311 | Product = ProductMap(Index) 312 | VerifyConfig 313 | End Sub 314 | 315 | Private Sub cmbClient_Click() 316 | cmbClient_Change 317 | End Sub 318 | 319 | Private Sub cmbClient_KeyPress(KeyAscii As Integer) 320 | cmbClient_Change 321 | End Sub 322 | 323 | Private Sub cmdExit_Click() 324 | Unload Me 325 | End Sub 326 | 327 | Private Sub Form_Load() 328 | On Error GoTo DLL_Error 329 | ' First, check that the BNCSutil library is 330 | ' available and recent enough to use. 331 | If (Not bncsutil_checkVersion("1.2.0")) Then 332 | MsgBox "The available BNCSutil library is too old to use. " & _ 333 | "BNCSutil 1.2.0 and up is required. (You have " & BNCSutil.Version & ".)", vbCritical, "Example Bot" 334 | End 335 | End If 336 | On Error GoTo Startup_Error 337 | ' Note: It is no longer necessary to call kd_init(). 338 | 339 | ' Add the list of clients. 340 | With frmMain.cmbClient 341 | .AddItem "StarCraft" 342 | .AddItem "Brood War" 343 | .AddItem "WarCraft II BNE" 344 | .AddItem "Diablo II" 345 | .AddItem "Lord of Destruction" 346 | .AddItem "WarCraft III" 347 | .AddItem "Frozen Throne" 348 | End With 349 | 350 | ' Set up combo box -> product code mapping 351 | ReDim ProductMap(6) As BNCSProducts 352 | ProductMap(0) = STAR 353 | ProductMap(1) = SEXP 354 | ProductMap(2) = W2BN 355 | ProductMap(3) = D2DV 356 | ProductMap(4) = D2XP 357 | ProductMap(5) = WAR3 358 | ProductMap(6) = W3XP 359 | 360 | Product = UNKN 361 | 362 | chkChangePassword_Click 363 | 364 | ' "Verify" the fields (which will of course fail), 365 | ' setting up the Status label in the process. 366 | VerifyConfig 367 | 368 | ' If InternalDebugMessages is False, bncsutil.dll was 369 | ' not compiled with debugging messages. 370 | chkDebug.Enabled = BNCSutil.InternalDebugMessages 371 | If (BNCSutil.DebugMode) Then 372 | chkDebug.Value = vbChecked 373 | Else 374 | chkDebug.Value = vbUnchecked 375 | End If 376 | Exit Sub 377 | Startup_Error: 378 | ' Generic error. 379 | MsgBox "The bot failed to start. (" & Err.Description & " - #" & _ 380 | Err.Number & ")", vbCritical, "Example Bot" 381 | End 382 | Exit Sub 383 | DLL_Error: 384 | ' This code will be run if there was a problem 385 | ' calling bncsutil_checkVersion, indicating 386 | ' a problem with finding or loading the DLL. 387 | MsgBox "The BNCSutil library could not be loaded, and the bot must close.", _ 388 | vbCritical, "Example Bot" 389 | End 390 | End Sub 391 | 392 | Private Sub cmdBrowseHashes_Click() 393 | Dim Folder As String 394 | Folder = BrowseForFolder() 395 | If (Folder <> vbNullString) Then 396 | txtHashFolder.Text = Folder 397 | End If 398 | End Sub 399 | 400 | Private Sub cmdConnect_Click() 401 | If Not IsConnected Then 402 | UpdateStatus "Connecting..." 403 | cmdConnect.Caption = "Disconnect" 404 | Connect 405 | Else 406 | Disconnect 407 | End If 408 | End Sub 409 | 410 | Private Sub Form_Unload(Cancel As Integer) 411 | If (IsConnected) Then 412 | Disconnect 413 | End If 414 | 415 | If (BNCSutil.DebugMode) Then 416 | BNCSutil.DebugMode = False 417 | End If 418 | End Sub 419 | 420 | Private Sub txtCDKey_Change(Index As Integer) 421 | VerifyConfig 422 | End Sub 423 | 424 | Private Sub txtHashFolder_Change() 425 | VerifyConfig 426 | End Sub 427 | 428 | Private Sub txtHome_Change() 429 | VerifyConfig 430 | End Sub 431 | 432 | Private Sub txtNewPassword_Change() 433 | VerifyConfig 434 | End Sub 435 | 436 | Private Sub txtNewPassword2_Change() 437 | VerifyConfig 438 | End Sub 439 | 440 | Private Sub txtPassword_Change() 441 | VerifyConfig 442 | End Sub 443 | 444 | Private Sub txtServer_Change() 445 | VerifyConfig 446 | End Sub 447 | 448 | Private Sub txtUsername_Change() 449 | VerifyConfig 450 | End Sub 451 | 452 | Private Sub WS_Close() 453 | IsConnected = False 454 | UpdateStatus "Disconnected." 455 | cmdConnect.Caption = "Connect" 456 | End Sub 457 | 458 | Private Sub WS_Connect() 459 | IsConnected = True 460 | 461 | UpdateStatus "Connected." 462 | 463 | ' Let Battle.Net know that we're using the binary protocol. 464 | WS.SendData Chr$(1) 465 | 466 | ' Send SID_AUTH_INFO (0x50) 467 | SendAuthInfo 468 | End Sub 469 | 470 | Private Sub WS_DataArrival(ByVal bytesTotal As Long) 471 | Dim Data As String 472 | 473 | ' Get the data that was just received. 474 | WS.GetData Data, vbString 475 | 476 | ' Pass it to the first-pass parser. 477 | HandleData Data, bytesTotal 478 | End Sub 479 | 480 | Private Sub WS_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) 481 | UpdateStatus "Socket Error: " & Description & " (#" & Number & ")", stError 482 | IsConnected = False 483 | cmdConnect.Caption = "Connect" 484 | End Sub 485 | -------------------------------------------------------------------------------- /vb6_example/frmNewAccount.frm: -------------------------------------------------------------------------------- 1 | VERSION 5.00 2 | Begin VB.Form frmNewAccount 3 | BorderStyle = 3 'Fixed Dialog 4 | Caption = "Account Does Not Exist" 5 | ClientHeight = 2535 6 | ClientLeft = 45 7 | ClientTop = 360 8 | ClientWidth = 5535 9 | BeginProperty Font 10 | Name = "Tahoma" 11 | Size = 8.25 12 | Charset = 0 13 | Weight = 400 14 | Underline = 0 'False 15 | Italic = 0 'False 16 | Strikethrough = 0 'False 17 | EndProperty 18 | Icon = "frmNewAccount.frx":0000 19 | LinkTopic = "Form1" 20 | MaxButton = 0 'False 21 | MinButton = 0 'False 22 | ScaleHeight = 2535 23 | ScaleWidth = 5535 24 | ShowInTaskbar = 0 'False 25 | StartUpPosition = 3 'Windows Default 26 | Begin VB.TextBox txtConfirm 27 | Height = 285 28 | IMEMode = 3 'DISABLE 29 | Left = 1800 30 | PasswordChar = "*" 31 | TabIndex = 6 32 | Top = 1410 33 | Width = 3015 34 | End 35 | Begin VB.Frame fraButtons 36 | Height = 975 37 | Left = -240 38 | TabIndex = 1 39 | Top = 1800 40 | Width = 6135 41 | Begin VB.CommandButton cmdAbort 42 | Cancel = -1 'True 43 | Caption = "Abort" 44 | Height = 375 45 | Left = 2760 46 | TabIndex = 3 47 | Top = 240 48 | Width = 1215 49 | End 50 | Begin VB.CommandButton cmdCreate 51 | Caption = "Create Account" 52 | Default = -1 'True 53 | Height = 375 54 | Left = 4080 55 | TabIndex = 2 56 | Top = 240 57 | Width = 1575 58 | End 59 | End 60 | Begin VB.Label Label1 61 | Caption = "Confirm Password:" 62 | Height = 255 63 | Left = 120 64 | TabIndex = 5 65 | Top = 1440 66 | Width = 1575 67 | End 68 | Begin VB.Label lblStatus 69 | Caption = "If you would like to create the account, you must confirm your password." 70 | Height = 495 71 | Left = 120 72 | TabIndex = 4 73 | Top = 720 74 | Width = 5415 75 | End 76 | Begin VB.Label lblQuestion 77 | Caption = "The account you have specified (""MMMMMMMMMMMMMMMM"") does not exist. What would you like to do?" 78 | Height = 495 79 | Left = 120 80 | TabIndex = 0 81 | Top = 120 82 | Width = 5295 83 | End 84 | End 85 | Attribute VB_Name = "frmNewAccount" 86 | Attribute VB_GlobalNameSpace = False 87 | Attribute VB_Creatable = False 88 | Attribute VB_PredeclaredId = True 89 | Attribute VB_Exposed = False 90 | Option Explicit 91 | 92 | Private Sub cmdAbort_Click() 93 | Disconnect 94 | Unload Me 95 | End Sub 96 | 97 | Private Sub cmdCreate_Click() 98 | If LenB(txtConfirm.Text) = 0 Then 99 | lblStatus.ForeColor = vbRed 100 | lblStatus.Caption = "If you would like to create the account, you must confirm your password." 101 | Exit Sub 102 | End If 103 | 104 | If (frmMain.txtPassword.Text <> txtConfirm.Text) Then 105 | lblStatus.ForeColor = vbRed 106 | lblStatus.Caption = "The confirmation you entered does not match the password you previously entered." 107 | Exit Sub 108 | End If 109 | 110 | AccountCreateAccepted 111 | Unload Me 112 | End Sub 113 | 114 | Private Sub Form_Load() 115 | lblQuestion.Caption = "The account you have specified (""" & _ 116 | frmMain.txtUsername.Text & """) does not exist. What would you like to do?" 117 | lblStatus.ForeColor = vbButtonText 118 | lblStatus.Caption = "If you would like to create the account, you must confirm your password." 119 | End Sub 120 | -------------------------------------------------------------------------------- /vb6_example/frmNewAccount.frx: -------------------------------------------------------------------------------- 1 | lt --------------------------------------------------------------------------------