pax_global_header00006660000000000000000000000064152367216710014524gustar00rootroot0000000000000052 comment=6334e0bde9cb7d2df73f7f9aa1072b54210a4d21 bncsutil-1.4.5/000077500000000000000000000000001523672167100133565ustar00rootroot00000000000000bncsutil-1.4.5/.clang-format.todo000066400000000000000000000001571523672167100167000ustar00rootroot00000000000000Language: Cpp BasedOnStyle: llvm Standard: c++11 TabWidth: 4 PointerAlignment: Right NamespaceIndentation: Nonebncsutil-1.4.5/.clang-tidy000066400000000000000000000027731523672167100154230ustar00rootroot00000000000000Checks: ' bugprone-* ,cert-* ,cppcoreguidelines-* ,modernize-* ,performance-* ,readability-* ,portability-* ,clang-analyzer-unix ,clang-analyzer-security ,clang-analyzer-deadcode ,clang-analyzer-core ,clang-analyzer-cplusplus ,clang-analyzer-optin ,llvm-namespace-comment ,readability-static-accessed-through-instance ,misc-const-correctness ,-bugprone-reserved-identifier ,-bugprone-implicit-widening-of-multiplication-result ,-bugprone-easily-swappable-parameters ,-bugprone-narrowing-conversions ,-cert-dcl37-c ,-cert-dcl51-cpp ,-cert-msc32-c ,-cert-msc51-cpp ,-cert-msc30-c ,-cert-msc50-cpp ,-modernize-use-trailing-return-type ,-modernize-macro-to-enum ,-modernize-use-nullptr ,-modernize-use-using ,-modernize-avoid-c-arrays ,-modernize-use-auto ,-readability-avoid-unconditional-preprocessor-if ,-readability-identifier-length ,-readability-isolate-declaration ,-readability-magic-numbers ,-readability-braces-around-statements ,-readability-function-cognitive-complexity ,-cppcoreguidelines-macro-to-enum ,-cppcoreguidelines-macro-usage ,-cppcoreguidelines-pro-bounds-pointer-arithmetic ,-cppcoreguidelines-pro-type-cstyle-cast ,-cppcoreguidelines-init-variables ,-cppcoreguidelines-avoid-magic-numbers ,-cppcoreguidelines-pro-bounds-array-to-pointer-decay ,-cppcoreguidelines-avoid-c-arrays ,-cppcoreguidelines-narrowing-conversions 'bncsutil-1.4.5/.github/000077500000000000000000000000001523672167100147165ustar00rootroot00000000000000bncsutil-1.4.5/.github/workflows/000077500000000000000000000000001523672167100167535ustar00rootroot00000000000000bncsutil-1.4.5/.github/workflows/cmake.yml000066400000000000000000000061401523672167100205570ustar00rootroot00000000000000name: CMake on: [push, pull_request] env: BUILD_TYPE: Release jobs: build-debian-system-reproducible: if: true runs-on: ubuntu-latest container: image: debian:trixie steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install dependencies run: apt-get -y update && apt-get install -y libgmp-dev build-essential cmake - name: Cmake pass 1 run: cmake -G "Unix Makefiles" -B./build1 -DCMAKE_BUILD_TYPE=$BUILD_TYPE - name: Build pass 1 run: cmake --build ./build1 - name: Cmake pass 2 run: cmake -G "Unix Makefiles" -B./build2 -DCMAKE_BUILD_TYPE=$BUILD_TYPE - name: Build pass 2 run: cmake --build ./build2 - name: Check hashes run: | ls -la build1 hash1=$(sha256sum build1/libbncsutil.so | cut -d ' ' -f 1) hash2=$(sha256sum build2/libbncsutil.so | cut -d ' ' -f 1) echo "Hash 1: $hash1\n" echo "Hash 2: $hash2\n" [ "$hash1" = "$hash2" ] && exit 0 || exit 1 build-debian-conan: if: true runs-on: ubuntu-latest container: image: debian:trixie steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install dependencies run: apt-get -y update && apt-get install -y python3 python3-pip build-essential cmake - name: Install conan run: pip install conan --break-system-packages - name: Init conan run: conan profile detect - name: Install deps with conan run: conan install . -of build -s build_type=$BUILD_TYPE --build=missing - name: Cmake working-directory: build run: bash conanbuild.sh && cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DUSE_SYSTEM_LIBS=0 - name: Build working-directory: build run: cmake --build . --config Release build-fedora-system: if: true runs-on: ubuntu-latest container: image: fedora:latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install dependencies run: dnf -y install gmp-devel make automake clang cmake - name: Cmake run: cmake -G "Unix Makefiles" -B./build -DCMAKE_BUILD_TYPE=$BUILD_TYPE - name: Build run: cmake --build ./build build-windows-conan: if: true runs-on: windows-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: TheMrMilchmann/setup-msvc-dev@79dac248aac9d0059f86eae9d8b5bfab4e95e97c # v4 with: arch: x64 - name: Install Conan id: conan uses: turtlebrowser/get-conan@c171f295f3f507360ee018736a6608731aa2109d # v1.2 - name: Init conan run: conan profile detect - name: Install dependencies shell: cmd run: conan install . -of build -s build_type=Release -o *:shared=False --build=missing - name: Build shell: cmd working-directory: ./build run: .\conanbuild.bat && cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DBUILD_SHARED_LIBS=1 && cmake --build . --config Release bncsutil-1.4.5/.github/workflows/release.yml000066400000000000000000000151261523672167100211230ustar00rootroot00000000000000name: Release on: push: tags: - '*' env: BUILD_TYPE: Release jobs: deb: if: true runs-on: ubuntu-latest container: image: debian:trixie steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install dependencies run: apt-get -y update && apt-get install -y libgmp-dev build-essential cmake - name: Cmake run: cmake -G "Unix Makefiles" -B./build -DCMAKE_BUILD_TYPE=$BUILD_TYPE - name: Build run: cmake --build ./build - name: Package id: package working-directory: build run: | cpack -G "DEB" -D CPACK_PACKAGE_FILE_NAME=libbncsutil-dev_${{ github.ref_name }}_amd64 - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: retention-days: 1 overwrite: true name: libbncsutil-dev_${{ github.ref_name }}_amd64.deb path: build/libbncsutil-dev_${{ github.ref_name }}_amd64.deb rpm: if: true runs-on: ubuntu-latest container: image: fedora:latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install dependencies run: dnf -y install gmp-devel make automake clang cmake rpm-build - name: Cmake run: cmake -G "Unix Makefiles" -B./build -DCMAKE_BUILD_TYPE=$BUILD_TYPE - name: Build run: cmake --build ./build - name: Package working-directory: build run: cpack -G "RPM" -D CPACK_PACKAGE_FILE_NAME=libbncsutil-devel-${{ github.ref_name }}.x86_64 - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: retention-days: 1 overwrite: true name: libbncsutil-devel-${{ github.ref_name }}.x86_64.rpm path: build/libbncsutil-devel-${{ github.ref_name }}.x86_64.rpm dll_amd64: if: true runs-on: windows-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: TheMrMilchmann/setup-msvc-dev@79dac248aac9d0059f86eae9d8b5bfab4e95e97c # v4 with: arch: x64 - name: Cache Conan uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 with: key: conan-windows-amd64-${{ hashFiles('conanfile.py') }} path: | ~/.conan2/p - name: Install Conan id: conan uses: turtlebrowser/get-conan@c171f295f3f507360ee018736a6608731aa2109d # v1.2 - name: Init conan run: conan profile detect - name: Install dependencies shell: cmd run: conan install . -of build -s build_type=Release -o *:shared=False --build=missing - name: Build shell: cmd working-directory: ./build run: .\conanbuild.bat && cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DBUILD_SHARED_LIBS=1 && cmake --build . --config Release - name: Create archive working-directory: ./build run: | New-Item -ItemType Directory -Path include/bncsutil -Force | Out-Null Copy-Item -Path '../src/bncsutil/*.h' -Destination include/bncsutil Compress-Archive -Path Release/* -DestinationPath bncsutil_${{ github.ref_name }}_amd64_dll.zip Compress-Archive -Path include -DestinationPath "bncsutil_${{ github.ref_name }}_amd64_dll.zip" -Update - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: retention-days: 1 overwrite: true name: bncsutil_${{ github.ref_name }}_amd64_dll.zip path: build/bncsutil_${{ github.ref_name }}_amd64_dll.zip dll_x86: if: true runs-on: windows-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: TheMrMilchmann/setup-msvc-dev@79dac248aac9d0059f86eae9d8b5bfab4e95e97c # v4 with: arch: x86 - name: Install Conan id: conan uses: turtlebrowser/get-conan@c171f295f3f507360ee018736a6608731aa2109d # v1.2 - name: Cache Conan uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 with: key: conan-windows-x86-${{ hashFiles('conanfile.py') }} path: | ~/.conan2/p - name: Init conan run: conan profile detect - name: Install dependencies shell: cmd run: conan install . -of build -s build_type=Release -s:h arch=x86 -o *:shared=False --build=missing - name: Build shell: cmd working-directory: ./build run: .\conanbuild.bat && cmake .. -DCMAKE_GENERATOR_PLATFORM=x86 -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DBUILD_SHARED_LIBS=1 && cmake --build . --config Release - name: Create archive working-directory: ./build run: | New-Item -ItemType Directory -Path include/bncsutil -Force | Out-Null Copy-Item -Path '../src/bncsutil/*.h' -Destination include/bncsutil Compress-Archive -Path Release/* -DestinationPath bncsutil_${{ github.ref_name }}_x86_dll.zip Compress-Archive -Path include -DestinationPath "bncsutil_${{ github.ref_name }}_x86_dll.zip" -Update - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: retention-days: 1 overwrite: true name: bncsutil_${{ github.ref_name }}_x86_dll.zip path: build/bncsutil_${{ github.ref_name }}_x86_dll.zip release: needs: [deb, rpm, dll_amd64, dll_x86] runs-on: ubuntu-latest steps: - name: Download deb uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: libbncsutil-dev_${{ github.ref_name }}_amd64.deb - name: Download rpm uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: libbncsutil-devel-${{ github.ref_name }}.x86_64.rpm - name: Download dll amd64 uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: bncsutil_${{ github.ref_name }}_amd64_dll.zip - name: Download dll x86 uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: bncsutil_${{ github.ref_name }}_x86_dll.zip - name: Create GitHub Release uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2 with: files: | libbncsutil-dev_${{ github.ref_name }}_amd64.deb libbncsutil-devel-${{ github.ref_name }}.x86_64.rpm bncsutil_${{ github.ref_name }}_amd64_dll.zip bncsutil_${{ github.ref_name }}_x86_dll.zip tag_name: ${{ github.ref_name }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}bncsutil-1.4.5/.gitignore000066400000000000000000000007021523672167100153450ustar00rootroot00000000000000*.7z *.app *.bak *.class *.diff *.dll *.dmg *.err *.gz *.iso *.jar *.lib *.log *.o *.patch *.rar *.so *.swp *.tar *.tgz *.vi *.vim *.zip .DS_Store .Spotlight-V100 .Trashes ._* CMakeCache.txt CMakeFiles/ CPackConfig.cmake CPackSourceConfig.cmake Debug/ Makefile Release/ Thumbs.db build/ cmake_install.cmake Findmpir.cmake conan.lock conanbuildinfo.txt conaninfo.txt graph_info.json CMakeUserPresets.json cmake-* .idea/ obj-x86_64-linux-gnu/ .claude/ bncsutil-1.4.5/CMake/000077500000000000000000000000001523672167100143365ustar00rootroot00000000000000bncsutil-1.4.5/CMake/Modules/000077500000000000000000000000001523672167100157465ustar00rootroot00000000000000bncsutil-1.4.5/CMake/Modules/FindGMP.cmake000066400000000000000000000012611523672167100201740ustar00rootroot00000000000000# Try to find the GMP librairies # GMP_FOUND - system has GMP lib # GMP_INCLUDE_DIR - the GMP include directory # GMP_LIBRARIES - Libraries needed to use GMP if (GMP_INCLUDE_DIR AND GMP_LIBRARIES) set(GMP_FIND_QUIETLY TRUE) endif (GMP_INCLUDE_DIR AND GMP_LIBRARIES) find_path(GMP_INCLUDE_DIR NAMES gmp.h PATHS ${CMAKE_SOURCE_DIR}/depends/include) find_library(GMP_LIBRARIES NAMES gmp libgmp libgmp.so.10 PATHS ${CMAKE_SOURCE_DIR}/depends/lib ) MESSAGE(STATUS "GMP libs: " ${GMP_LIBRARIES} " " ${GMPXX_LIBRARIES} ) include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMP DEFAULT_MSG GMP_INCLUDE_DIR GMP_LIBRARIES) mark_as_advanced(GMP_INCLUDE_DIR GMP_LIBRARIES) bncsutil-1.4.5/CMake/bncsutilConfig.cmake.in000066400000000000000000000003041523672167100207130ustar00rootroot00000000000000@PACKAGE_INIT@ include("${CMAKE_CURRENT_LIST_DIR}/bncsutilTargets.cmake") set(bncsutil_FOUND TRUE) set(bncsutil_VERSION "@PROJECT_VERSION@") message(STATUS "Found bncsutil: ${bncsutil_VERSION}")bncsutil-1.4.5/CMakeLists.txt000066400000000000000000000116561523672167100161270ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.25) project(bncsutil VERSION 1.4.5) set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR} "${PROJECT_SOURCE_DIR}/CMake/Modules") add_library(bncsutil SHARED) set(HEADERS "src/bncsutil/bncsutil.h" "src/bncsutil/bsha1.h" "src/bncsutil/buffer.h" "src/bncsutil/cdkeydecoder.h" "src/bncsutil/checkrevision.h" "src/bncsutil/decodekey.h" "src/bncsutil/keytables.h" "src/bncsutil/libinfo.h" "src/bncsutil/mutil.h" "src/bncsutil/mutil_types.h" "src/bncsutil/nls.h" "src/bncsutil/oldauth.h" "src/bncsutil/pe.h" "src/bncsutil/sha1.h" ) set(SOURCES "src/bncsutil/bsha1.cpp" "src/bncsutil/cdkeydecoder.cpp" "src/bncsutil/checkrevision.cpp" "src/bncsutil/decodekey.cpp" "src/bncsutil/file.cpp" "src/bncsutil/libinfo.cpp" "src/bncsutil/nls.c" "src/bncsutil/oldauth.cpp" "src/bncsutil/pe.c" "src/bncsutil/sha1.c" "src/bncsutil/stack.c" ) target_sources(bncsutil PRIVATE ${SOURCES} ${HEADERS}) if(WIN32) option(USE_SYSTEM_LIBS "Use system libraries" OFF) else() option(USE_SYSTEM_LIBS "Use system libraries" ON) endif() if(CMAKE_GENERATOR_PLATFORM STREQUAL "x86") target_compile_options(bncsutil PRIVATE -m32) target_link_options(bncsutil PRIVATE -m32) message(STATUS "Excluding 64bit library paths from search.") set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS OFF) elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "x64") target_compile_options(bncsutil PRIVATE -m64) target_link_options(bncsutil PRIVATE -m64) endif() if(USE_SYSTEM_LIBS) message(STATUS "Using system dependencies") find_package(GMP REQUIRED) target_include_directories(bncsutil PRIVATE src ${GMP_INCLUDE_DIR}) target_link_libraries(bncsutil PRIVATE ${GMP_LIBRARIES}) else() message(STATUS "Using conan dependencies") find_package(gmp REQUIRED) target_include_directories(bncsutil PRIVATE src) target_link_libraries(bncsutil PRIVATE gmp::gmp) endif() target_compile_definitions(bncsutil PRIVATE MUTIL_LIB_BUILD) if(UNIX) set_target_properties(bncsutil PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} ) target_compile_options(bncsutil PRIVATE -Wall -O3 -Wno-multichar -fPIC -fvisibility=hidden $<$:-fvisibility-inlines-hidden> ) target_link_options(bncsutil PRIVATE -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/bncsutil.map ) endif() if(WIN32) target_compile_definitions(bncsutil PRIVATE _CRT_SECURE_NO_WARNINGS) endif() if(MSVC) set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "bncsutil") endif() include(CMakePackageConfigHelpers) include(GNUInstallDirs) install(TARGETS bncsutil EXPORT bncsutilTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/bncsutil) install(EXPORT bncsutilTargets FILE bncsutilTargets.cmake NAMESPACE bncsutil:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/bncsutil ) configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/bncsutilConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/bncsutilConfig.cmake" INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/bncsutil ) write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/bncsutilConfigVersion.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/bncsutilConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/bncsutilConfigVersion.cmake" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/bncsutil ) # CPack configuration set(CPACK_GENERATOR "DEB" "RPM") set(CPACK_PACKAGE_NAME "bncsutil") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Battle.Net Chat Service Utility") set(CPACK_PACKAGE_VENDOR "bncsutil") set(CPACK_PACKAGE_DESCRIPTION "\ This will install the library to /usr/local/lib and header files to /usr/local/include.\n \ Make sure these directories are in your library and include paths. \ ") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/local") # DEB configuration set(CPACK_DEBIAN_PACKAGE_SECTION "libs") set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/BNETDocs/bncsutil") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "imbacen@gmail.com") set(CPACK_DEBIAN_PACKAGE_DEPENDS "libgmp10") # RPM configuration set(CPACK_RPM_PACKAGE_RELEASE 1) set(CPACK_RPM_PACKAGE_LICENSE "LGPL-2.1") set(CPACK_RPM_PACKAGE_GROUP "bncsutil") set(CPACK_RPM_PACKAGE_URL "https://github.com/BNETDocs/bncsutil") set(CPACK_RPM_PACKAGE_REQUIRES "gmp") include(CPack) bncsutil-1.4.5/COPYING000066400000000000000000000636421523672167100144240ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! bncsutil-1.4.5/README.md000066400000000000000000000110461523672167100146370ustar00rootroot00000000000000# BNCSUtil [![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) [![GitHub top language](https://img.shields.io/github/languages/top/BNETDocs/bncsutil?style=flat)](https://github.com/BNETDocs/bncsutil) ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/BNETDocs/bncsutil?style=flat) [![License Badge](https://img.shields.io/github/license/BNETDocs/bncsutil?style=flat)](https://github.com/BNETDocs/bncsutil/blob/master/COPYING) [![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) [![GitHub All Releases](https://img.shields.io/github/downloads/BNETDocs/bncsutil/total?style=flat)](https://github.com/BNETDocs/bncsutil/releases/latest) **BNCSUtil** is the **B**attle.**N**et **C**hat **S**ervice **Util**ity which aids applications trying to logon to Classic Battle.net™ using the binary protocol. Specifically, BNCSUtil has functions that help with the cryptography of game versions, keys, and passwords. BNCSUtil was originally written by Eric Naeseth (shadypalm88) and has since been maintained over the course of several years by the open source Battle.net community. # Usage `#include ` and link against `bncsutil.lib` or `libbncsutil.so`. For CMake add: ``` find_package(bncsutil REQUIRED) target_link_libraries(mytarget PRIVATE bncsutil::bncsutil) ``` # Building To force a specific build (32bit or 64bit) add `-DCMAKE_GENERATOR_PLATFORM=x86` or `-DCMAKE_GENERATOR_PLATFORM=x64` to CMake flags. Change `BUILD_SHARED_LIBS` to build the library as static or shared. ## Windows Visual Studio 2022 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). In `cmd` or Visual Studio dev console run: ### amd64 ``` "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat" x64 conan install . -of build -s build_type=Release -o *:shared=False --build=missing cd build .\conanbuild.bat cmake .. -G "Visual Studio 17 2022" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DBUILD_SHARED_LIBS=1 cmake --build . --config Release ``` ### x86 ``` "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat" x86 conan install . -of build -s build_type=Release -s:h arch=x86 -o *:shared=False --build=missing cd build .\conanbuild.bat cmake .. -G "Visual Studio 17 2022" -DCMAKE_GENERATOR_PLATFORM=x86 -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DBUILD_SHARED_LIBS=1 cmake --build . --config Release ``` Alternatively open `build/bncsutil.sln` and build from Visual Studio. ## Linux ### Using system dependencies 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`). ``` cmake -G "Unix Makefiles" -B./build cd build cmake --build . --target install --config Release ``` ### Using conan 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. ``` conan install . -of build -s build_type=Release --build=missing cd build bash conanbuild.sh cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DUSE_SYSTEM_LIBS=0 cmake --build . --config Release ``` ## .deb and .rpm packages After invoking CMake, cd to build folder and generate them with `cpack -G "DEB"` and `cpack -G "RPM"`. 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`. Note that this is a "development" package which also includes header files. Library installs to `/usr/local/lib`, include files in `/usr/local/include/bncsutil`. Packages are also available for download from github releases built on Debian Bookworm and Fedora latest. # Development with CLion 1. Run conan from cli as per build instructions above 2. Open the project 3. Tools -> CMake -> Change Project Root -> build 4. Settings -> Build, Execution, Deployment -> CMake -> Add at least this cmake option: -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake bncsutil-1.4.5/bncsutil.map000066400000000000000000000026311523672167100157020ustar00rootroot00000000000000{ global: /* bsha1 */ calcHashBuf; /* checkrevision */ checkRevision; checkRevisionFlat; extractMPQNumber; getExeInfo; get_mpq_seed; set_mpq_seed; /* decodekey (C wrappers) */ kd_calculateHash; kd_create; kd_free; kd_getHash; kd_init; kd_isValid; kd_longVal2; kd_product; kd_quick; kd_val1; kd_val2; kd_val2Length; /* libinfo */ bncsutil_getVersion; bncsutil_getVersionString; /* nls */ nls_account_change_proof; nls_account_create; nls_account_logon; nls_check_M2; nls_check_signature; nls_free; nls_get_A; nls_get_K; nls_get_M1; nls_get_S; nls_get_v; nls_init; nls_init_l; nls_reinit; nls_reinit_l; /* oldauth */ doubleHashPassword; hashPassword; /* pe */ cm_pe_fixed_version; cm_pe_load; cm_pe_load_resources; cm_pe_unload; cm_pe_unload_resources; /* CDKeyDecoder C++ class (methods, vtable, typeinfo) */ _ZN12CDKeyDecoder*; _ZTI12CDKeyDecoder; _ZTS12CDKeyDecoder; _ZTV12CDKeyDecoder; local: *; }; bncsutil-1.4.5/conanfile.py000066400000000000000000000025731523672167100156750ustar00rootroot00000000000000from conan import ConanFile from conan.tools.files import copy from conan.tools.files import rename import os class Bncsutil(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" requires = ( "gmp/6.3.0", ) def generate(self): # Workaround for a conan bug producing wrongly named libraries.. if self.settings.os == "Windows": gmp_libdir = self.dependencies["gmp"].cpp_info.libdir gmp_from_name = f"{gmp_libdir}\libgmp.a" gmp_to_name = f"{gmp_libdir}\gmp.lib" gmpxx_from_name = f"{gmp_libdir}\libgmpxx.a" gmpxx_to_name = f"{gmp_libdir}\gmpxx.lib" if os.path.isfile(gmp_from_name): print("Renaming " + gmp_from_name + " to " + gmp_to_name) rename(self, gmp_from_name, gmp_to_name) if os.path.isfile(gmpxx_from_name): print("Renaming " + gmpxx_from_name + " to " + gmpxx_to_name) rename(self, gmpxx_from_name, gmpxx_to_name) for dep in self.dependencies.values(): if dep.cpp_info.libdirs: copy(self, "*.lib", dep.cpp_info.libdirs[0], self.build_folder) if dep.cpp_info.bindirs: copy(self, "*.dll", dep.cpp_info.bindirs[0], self.build_folder)bncsutil-1.4.5/src/000077500000000000000000000000001523672167100141455ustar00rootroot00000000000000bncsutil-1.4.5/src/bncsutil/000077500000000000000000000000001523672167100157705ustar00rootroot00000000000000bncsutil-1.4.5/src/bncsutil/bncsutil.h000066400000000000000000000030121523672167100177600ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Common Interface * November 20, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef BNCSUTIL_BNCSUTIL_H_INCLUDED #define BNCSUTIL_BNCSUTIL_H_INCLUDED #include /* Myriad Utility Header */ #include /* CheckRevision / EXE info */ #include /* Broken SHA-1 */ #include /* Old Logon System */ #include /* CD-Key Decoding C wrappers */ #ifdef __cplusplus #include /* CD-Key Decoding Class */ #endif /* __cplusplus */ #include /* New Logon System */ #include /* BNCSutil Library Information */ #endif /* BNCSUTIL_BNCSUTIL_H_INCLUDED */ bncsutil-1.4.5/src/bncsutil/bsha1.cpp000066400000000000000000000202461523672167100174760ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Broken SHA-1 Implementation * October 23, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #include #include #include #define USE_NEW_BSHA1 0 #define BSHA_IC1 0x67452301lu #define BSHA_IC2 0xEFCDAB89lu #define BSHA_IC3 0x98BADCFElu #define BSHA_IC4 0x10325476lu #define BSHA_IC5 0xC3D2E1F0lu #define BSHA_OC1 0x5A827999lu #define BSHA_OC2 0x6ED9EBA1lu #define BSHA_OC3 0x70E44324lu #define BSHA_OC4 0x359D3E2Alu #if !USE_NEW_BSHA1 # define BSHA_COP e = d; d = c; c = ROL(b, 30); b = a; a = g; #else # define BSHA_N_COP t[4] = t[3]; t[3] = t[2]; t[2] = ROL(t[1], 30); \ t[1] = t[0]; t[0] = x #endif #if !USE_NEW_BSHA1 #define BSHA_OP1(a, b, c, d, e, f, g) g = LSB4(f) + ROL(a, 5) + e + \ ((b & c) | (~b & d)) + BSHA_OC1; BSHA_COP #define BSHA_OP2(a, b, c, d, e, f, g) g = (d ^ c ^ b) + e + ROL(g, 5) + \ LSB4(f) + BSHA_OC2; BSHA_COP #define BSHA_OP3(a, b, c, d, e, f, g) g = LSB4(f) + ROL(g, 5) + e + \ ((c & b) | (d & c) | (d & b)) - BSHA_OC3; BSHA_COP #define BSHA_OP4(a, b, c, d, e, f, g) g = (d ^ c ^ b) + e + ROL(g, 5) + \ LSB4(f) - BSHA_OC4; BSHA_COP #else #define BSHA_N_OP1() x = LSB4(*p++) + ROL(t[0], 5) + t[4] + \ ((t[1] & t[2]) | (~t[1] & t[3])) + BSHA_OC1; BSHA_N_COP #define BSHA_N_OP2() x = (t[3] ^ t[2] ^ t[1]) + t[4] + ROL(x, 5) + \ LSB4(*p++) + BSHA_OC2; BSHA_N_COP #define BSHA_N_OP3() x = LSB4(*p++) + ROL(x, 5) + t[4] + \ ((t[2] & t[1]) | (t[3] & t[2]) | (t[3] & t[1])) - BSHA_OC3; BSHA_N_COP #define BSHA_N_OP4() x = (t[3] ^ t[2] ^ t[1]) + t[4] + ROL(x, 5) + \ LSB4(*p++) - BSHA_OC4; BSHA_N_COP #endif #if USE_NEW_BSHA1 MEXP(void) calcHashBuf(const char* input, unsigned int length, char* result) { uint32_t vals[5]; uint32_t t[5]; // a, b, c, d, e uint32_t buf[0x50]; uint32_t* p; uint32_t x; const char* in = input; unsigned int i, j; unsigned int sub_length; /* Initializer Values */ p = vals; *p++ = BSHA_IC1; *p++ = BSHA_IC2; *p++ = BSHA_IC3; *p++ = BSHA_IC4; *p++ = BSHA_IC5; memset(buf, 0, 320); // zero buf /* Process input in chunks. */ for (i = 0; i < length; i += 0x40) { sub_length = length - i; /* Maximum chunk size is 0x40 (64) bytes. */ if (sub_length > 0x40) sub_length = 0x40; memcpy(buf, in, sub_length); in += sub_length; /* If necessary, pad with zeroes to 64 bytes. */ if (sub_length < 0x40) memset(buf + sub_length, 0, 0x40 - sub_length); for (j = 0; j < 64; j++) { buf[j + 16] = LSB4(ROL(1, LSB4(buf[j] ^ buf[j+8] ^ buf[j+2] ^ buf[j+13]) % 32)); } memcpy(t, vals, 20); p = buf; /* It's a kind of magic. */ BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP1(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP2(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP3(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); BSHA_N_OP4(); vals[0] += t[0]; vals[1] += t[1]; vals[2] += t[2]; vals[3] += t[3]; vals[4] += t[4]; } /* Return result. */ memcpy(result, vals, 20); } #else MEXP(void) calcHashBuf(const char* input, size_t length, char* result) { int i; uint32_t a, b, c, d, e, g; uint32_t* ldata; char data[1024]; memset(data, 0, 1024); memcpy(data, input, length); ldata = (uint32_t*) data; for (i = 0; i < 64; i++) { ldata[i + 16] = LSB4(ROL(1, LSB4(ldata[i] ^ ldata[i+8] ^ ldata[i+2] ^ ldata[i+13]) % 32)); } //dumpbuf(data, 1024); a = BSHA_IC1; b = BSHA_IC2; c = BSHA_IC3; d = BSHA_IC4; e = BSHA_IC5; g = 0; // Loops unrolled. BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP1(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP2(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP3(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) BSHA_OP4(a, b, c, d, e, *ldata++, g) ldata = (uint32_t*) result; ldata[0] = LSB4(BSHA_IC1 + a); ldata[1] = LSB4(BSHA_IC2 + b); ldata[2] = LSB4(BSHA_IC3 + c); ldata[3] = LSB4(BSHA_IC4 + d); ldata[4] = LSB4(BSHA_IC5 + e); ldata = NULL; } #endif bncsutil-1.4.5/src/bncsutil/bsha1.h000066400000000000000000000024641523672167100171450ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Broken SHA-1 Interface * October 23, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef BSHA1_H #define BSHA1_H #ifdef __cplusplus extern "C" { #endif /** * calcHashBuf * * Calculates a "Broken SHA-1" hash of data. * * Paramaters: * data: The data to hash. * length: The length of data. * hash: Buffer, at least 20 bytes in length, to receive the hash. */ MEXP(void) calcHashBuf(const char* data, size_t length, char* hash); #ifdef __cplusplus } // extern "C" #endif #endif bncsutil-1.4.5/src/bncsutil/buffer.h000066400000000000000000000041071523672167100174140ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Message Buffers * January 11, 2006 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef BUFFER_H #define BUFFER_H #include typedef struct msg_buffer *msg_buffer_t; typedef struct msg_buffer_impl *msg_buffer_impl_t; typedef struct msg_reader *msg_reader_t; typedef struct msg_reader_impl *msg_reader_impl_t; // Callbacks /** * Called to determine the number of bytes at the beginning of an output * buffer to reserve for a message/packet header. */ typedef size_t __stdcall (*buffer_bytes_to_reserve)(); /** * Called to generate the header on an outgoing packet. */ typedef int __stdcall (*buffer_create_header)(msg_buffer_t); /** * Creates a new generic buffer for an outgoing packet. */ msg_buffer_t create_buffer(size_t initial_size); /** * Creates a new BNCS buffer. */ msg_buffer_t create_bncs_buffer(size_t initial_size); /** * Destroys a message buffer. */ void destroy_buffer(msg_buffer_t); // Adders void buffer_add_8(msg_buffer_t, int8_t); void buffer_add_u8(msg_buffer_t, uint8_t); void buffer_add_16(msg_buffer_t, int16_t); void buffer_add_u16(msg_buffer_t, uint16_t); void buffer_add_32(msg_buffer_t, int32_t); void buffer_add_u32(msg_buffer_t, uint32_t); msg_reader_t create_reader(size_t initial_size); #endif /* BUFFER_H */ bncsutil-1.4.5/src/bncsutil/cdkeydecoder.cpp000066400000000000000000000371221523672167100211260ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * CD-Key Decoder Implementation * September 29, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #include #include #include // w2/d2 and w3 tables #include // Broken SHA-1 #include // US Secure Hash Algorithm (for W3) #include // for isdigit(), isalnum(), and toupper() #include // for memcpy() #include // for sscanf() /** * Implementation-specific CD-key hash structure. */ struct CDKEYHASH { uint32_t clientToken; uint32_t serverToken; uint32_t product; uint32_t value1; union { struct { uint32_t zero; uint32_t v; unsigned char reserved[2]; } s; struct { char v[10]; } l; } value2; }; #define W3_KEYLEN 26 #define W3_BUFLEN (W3_KEYLEN << 1) /** * Creates a new CD-key decoder object. * Not really useful unless subclassed. */ CDKeyDecoder::CDKeyDecoder() { initialized = 0; keyOK = 0; hashLen = 0; cdkey = (char*) 0; w3value2 = (char*) 0; keyHash = (char*) 0; } CDKeyDecoder::CDKeyDecoder(const char* cd_key) { CDKeyDecoder(cd_key, std::strlen(cd_key)); } /** * Creates a new CD-key decoder object, using the specified key. * keyLength should be the length of the key, NOT INCLUDING the * null-terminator. Applications should use isKeyValid after using * this constructor to check the validity of the provided key. */ CDKeyDecoder::CDKeyDecoder(const char* cdKey, size_t keyLength) { unsigned int i; initialized = 0; product = 0; value1 = 0; value2 = 0; keyOK = 0; hashLen = 0; cdkey = (char*) 0; w3value2 = (char*) 0; keyHash = (char*) 0; if (keyLength <= 0) return; // Initial sanity check if (keyLength == 13) { // StarCraft key for (i = 0; i < keyLength; i++) { if (!isdigit(cdKey[i])) return; } keyType = KEY_STARCRAFT; #if DEBUG bncsutil_debug_message_a( "Created CD key decoder with STAR key %s.", cdKey ); #endif } else { // D2/W2/W3 key for (i = 0; i < keyLength; i++) { if (!isalnum(cdKey[i])) return; } switch (keyLength) { case 16: keyType = KEY_WARCRAFT2; #if DEBUG bncsutil_debug_message_a( "Created CD key decoder with W2/D2 key %s.", cdKey ); #endif break; case 26: keyType = KEY_WARCRAFT3; #if DEBUG bncsutil_debug_message_a( "Created CD key decoder with WAR3 key %s.", cdKey ); #endif break; default: #if DEBUG bncsutil_debug_message_a( "Created CD key decoder with unrecognized key %s.", cdKey ); #endif return; } } cdkey = new char[keyLength + 1]; initialized = 1; keyLen = keyLength; memcpy(cdkey, cdKey, keyLength); cdkey[keyLength] = '\0'; switch (keyType) { case KEY_STARCRAFT: keyOK = processStarCraftKey(); #if DEBUG bncsutil_debug_message_a("%s: ok=%d; product=%d; public=%d; " "private=%d", cdkey, keyOK, getProduct(), getVal1(), getVal2()); #endif break; case KEY_WARCRAFT2: keyOK = processWarCraft2Key(); #if DEBUG bncsutil_debug_message_a("%s: ok=%d; product=%d; public=%d; " "private=%d", cdkey, keyOK, getProduct(), getVal1(), getVal2()); #endif break; case KEY_WARCRAFT3: keyOK = processWarCraft3Key(); #if DEBUG bncsutil_debug_message_a("%s: ok=%d; product=%d; public=%d; ", cdkey, keyOK, getProduct(), getVal1()); #endif break; default: return; } } CDKeyDecoder::~CDKeyDecoder() { if (initialized && cdkey != NULL) delete [] cdkey; if (hashLen > 0 && keyHash != NULL) delete [] keyHash; if (w3value2) delete [] w3value2; } int CDKeyDecoder::isKeyValid() { return (initialized && keyOK) ? 1 : 0; } int CDKeyDecoder::getVal2Length() { return (keyType == KEY_WARCRAFT3) ? 10 : 4; } uint32_t CDKeyDecoder::getProduct() { switch (keyType) { case KEY_STARCRAFT: case KEY_WARCRAFT2: return (uint32_t) LSB4(product); case KEY_WARCRAFT3: return (uint32_t) MSB4(product); default: return (uint32_t) -1; } } uint32_t CDKeyDecoder::getVal1() { switch (keyType) { case KEY_STARCRAFT: case KEY_WARCRAFT2: return (uint32_t) LSB4(value1); case KEY_WARCRAFT3: return (uint32_t) MSB4(value1); default: return (uint32_t) -1; } } uint32_t CDKeyDecoder::getVal2() { return (uint32_t) LSB4(value2); } int CDKeyDecoder::getLongVal2(char* out) { if (w3value2 != NULL && keyType == KEY_WARCRAFT3) { memcpy(out, w3value2, 10); return 10; } else { return 0; } } /** * Calculates the CD-Key hash for use in SID_AUTH_CHECK (0x51) * Returns the length of the generated hash; call getHash and pass * it a character array that is at least this size. Returns 0 on failure. * * Note that clientToken and serverToken will be added to the buffer and * hashed as-is, regardless of system endianness. It is assumed that * the program's extraction of the server token does not change its * endianness, and since the client token is generated by the client, * endianness is not a factor. */ size_t CDKeyDecoder::calculateHash(uint32_t clientToken, uint32_t serverToken) { struct CDKEYHASH kh; SHA1Context sha; if (!initialized || !keyOK) return 0; hashLen = 0; kh.clientToken = clientToken; kh.serverToken = serverToken; switch (keyType) { case KEY_STARCRAFT: case KEY_WARCRAFT2: kh.product = (uint32_t) LSB4(product); kh.value1 = (uint32_t) LSB4(value1); kh.value2.s.zero = 0; kh.value2.s.v = (uint32_t) LSB4(value2); keyHash = new char[20]; calcHashBuf((char*) &kh, 24, keyHash); hashLen = 20; #if DEBUG bncsutil_debug_message_a("%s: Hash calculated.", cdkey); bncsutil_debug_dump(keyHash, 20); #endif return 20; case KEY_WARCRAFT3: kh.product = (uint32_t) MSB4(product); kh.value1 = (uint32_t) MSB4(value1); memcpy(kh.value2.l.v, w3value2, 10); if (SHA1Reset(&sha)) return 0; if (SHA1Input(&sha, (const unsigned char*) &kh, 26)) return 0; keyHash = new char[20]; if (SHA1Result(&sha, (unsigned char*) keyHash)) { SHA1Reset(&sha); return 0; } SHA1Reset(&sha); hashLen = 20; #if DEBUG bncsutil_debug_message_a("%s: Hash calculated.", cdkey); bncsutil_debug_dump(keyHash, 20); #endif return 20; default: return 0; } } /** * Places the calculated CD-key hash in outputBuffer. You must call * calculateHash before getHash. Returns the length of the hash * that was copied to outputBuffer, or 0 on failure. */ size_t CDKeyDecoder::getHash(char* outputBuffer) { if (hashLen == 0 || !keyHash || !outputBuffer) return 0; memcpy(outputBuffer, keyHash, hashLen); return hashLen; } /* void CDKeyDecoder::swapChars(char* string, int a, int b) { char temp; temp = string[a]; string[a] = string[b]; string[b] = temp; } */ int CDKeyDecoder::processStarCraftKey() { int accum, pos, i; char temp; int hashKey = 0x13AC9741; char cdkey[14]; std::strcpy(cdkey, this->cdkey); // Verification accum = 3; for (i = 0; i < (int) (keyLen - 1); i++) { accum += ((tolower(cdkey[i]) - '0') ^ (accum * 2)); } if ((accum % 10) != (cdkey[12] - '0')) { // bncsutil_debug_message_a("error: %s is not a valid StarCraft key", cdkey); return 0; } // Shuffling pos = 0x0B; for (i = 0xC2; i >= 7; i -= 0x11) { temp = cdkey[pos]; cdkey[pos] = cdkey[i % 0x0C]; cdkey[i % 0x0C] = temp; pos--; } // Final Value for (i = (int) (keyLen - 2); i >= 0; i--) { temp = toupper(cdkey[i]); cdkey[i] = temp; if (temp <= '7') { cdkey[i] ^= (char) (hashKey & 7); hashKey >>= 3; } else if (temp < 'A') { cdkey[i] ^= ((char) i & 1); } } // Final Calculations sscanf(cdkey, "%2ld%7ld%3ld", &product, &value1, &value2); return 1; } int CDKeyDecoder::processWarCraft2Key() { unsigned long r, n, n2, v, v2, checksum; int i; unsigned char c1, c2, c; char cdkey[17]; std::strcpy(cdkey, this->cdkey); r = 1; checksum = 0; for (i = 0; i < 16; i += 2) { c1 = w2Map[(int) cdkey[i]]; n = c1 * 3; c2 = w2Map[(int) cdkey[i + 1]]; n = c2 + n * 8; if (n >= 0x100) { n -= 0x100; checksum |= r; } // ! n2 = n >> 4; // ! cdkey[i] = getHexValue(n2); cdkey[i + 1] = getHexValue(n); r <<= 1; } v = 3; for (i = 0; i < 16; i++) { c = cdkey[i]; n = getNumValue(c); n2 = v * 2; n ^= n2; v += n; } v &= 0xFF; if (v != checksum) { return 0; } n = 0; for (int j = 15; j >= 0; j--) { c = cdkey[j]; if (j > 8) { n = (j - 9); } else { n = (0xF - (8 - j)); } n &= 0xF; c2 = cdkey[n]; cdkey[j] = c2; cdkey[n] = c; } v2 = 0x13AC9741; for (int j = 15; j >= 0; j--) { c = toupper(cdkey[j]); cdkey[j] = c; if (c <= '7') { v = v2; c2 = (((char) (v & 0xFF)) & 7) ^ c; v >>= 3; cdkey[j] = (char) c2; v2 = v; } else if (c < 'A') { cdkey[j] = (((char) j) & 1) ^ c; } } // Final Calculations sscanf(cdkey, "%2lx%6lx%8lx", &product, &value1, &value2); return 1; } int CDKeyDecoder::processWarCraft3Key() { char table[W3_BUFLEN]; int values[4]; int a, b; int i; char decode; a = 0; b = 0x21; memset(table, 0, W3_BUFLEN); memset(values, 0, (sizeof(int) * 4)); for (i = 0; ((unsigned int) i) < keyLen; i++) { cdkey[i] = toupper(cdkey[i]); a = (b + 0x07B5) % W3_BUFLEN; b = (a + 0x07B5) % W3_BUFLEN; decode = w3KeyMap[(int)cdkey[i]]; table[a] = (decode / 5); table[b] = (decode % 5); } // Mult i = W3_BUFLEN; do { mult(4, 5, values + 3, table[i - 1]); } while (--i); decodeKeyTable(values); // 00 00 38 08 f0 64 18 6c 79 14 14 8E B9 49 1D BB // -------- // val1 product = values[0] >> 0xA; product = SWAP4(product); #if LITTLEENDIAN for (i = 0; i < 4; i++) { values[i] = MSB4(values[i]); } #endif value1 = LSB4(*(uint32_t*) (((char*) values) + 2)) & 0xFFFFFF03; w3value2 = new char[10]; #if LITTLEENDIAN *((uint16_t*) w3value2) = MSB2(*(uint16_t*) (((char*) values) + 6)); *((uint32_t*) ((char*) w3value2 + 2)) = MSB4(*(uint32_t*) (((char*) values) + 8)); *((uint32_t*) ((char*) w3value2 + 6)) = MSB4(*(uint32_t*) (((char*) values) + 12)); #else *((uint16_t*) w3value2) = LSB2(*(uint16_t*) (((char*) values) + 6)); *((uint32_t*) ((char*) w3value2 + 2)) = LSB4(*(uint32_t*) (((char*) values) + 8)); *((uint32_t*) ((char*) w3value2 + 6)) = LSB4(*(uint32_t*) (((char*) values) + 12)); #endif return 1; } inline void CDKeyDecoder::mult(int r, const int x, int* a, int dcByte) { while (r--) { int64_t edxeax = ((int64_t) (*a & 0x00000000FFFFFFFFl)) * ((int64_t) (x & 0x00000000FFFFFFFFl)); *a-- = dcByte + (int32_t) edxeax; dcByte = (int32_t) (edxeax >> 32); } } void CDKeyDecoder::decodeKeyTable(int* keyTable) { unsigned int eax, ebx, ecx, edx, edi, esi, ebp; unsigned int varC, var4, var8; unsigned int copy[4]; unsigned char* scopy; int* ckt; int ckt_temp; var8 = 29; int i = 464; // pass 1 do { int j; esi = (var8 & 7) << 2; var4 = var8 >> 3; //varC = (keyTable[3 - var4] & (0xF << esi)) >> esi; varC = keyTable[3 - var4]; varC &= (0xF << esi); varC = varC >> esi; if (i < 464) { for (j = 29; (unsigned int) j > var8; j--) { /* ecx = (j & 7) << 2; ebp = (keyTable[0x3 - (j >> 3)] & (0xF << ecx)) >> ecx; varC = w3TranslateMap[ebp ^ (w3TranslateMap[varC + i] + i)]; */ ecx = (j & 7) << 2; //ebp = (keyTable[0x3 - (j >> 3)] & (0xF << ecx)) >> ecx; ebp = (keyTable[0x3 - (j >> 3)]); ebp &= (0xF << ecx); ebp = ebp >> ecx; varC = w3TranslateMap[ebp ^ (w3TranslateMap[varC + i] + i)]; } } j = --var8; while (j >= 0) { ecx = (j & 7) << 2; //ebp = (keyTable[0x3 - (j >> 3)] & (0xF << ecx)) >> ecx; ebp = (keyTable[0x3 - (j >> 3)]); ebp &= (0xF << ecx); ebp = ebp >> ecx; varC = w3TranslateMap[ebp ^ (w3TranslateMap[varC + i] + i)]; j--; } j = 3 - var4; ebx = (w3TranslateMap[varC + i] & 0xF) << esi; keyTable[j] = (ebx | (~(0xF << esi) & ((int) keyTable[j]))); } while ((i -= 16) >= 0); // pass 2 eax = 0; edx = 0; ecx = 0; edi = 0; esi = 0; ebp = 0; for (i = 0; i < 4; i++) { copy[i] = LSB4(keyTable[i]); } scopy = (unsigned char*) copy; for (edi = 0; edi < 120; edi++) { unsigned int location = 12; eax = edi & 0x1F; ecx = esi & 0x1F; edx = 3 - (edi >> 5); location -= ((esi >> 5) << 2); ebp = *(int*) (scopy + location); ebp = LSB4(ebp); //ebp = (ebp & (1 << ecx)) >> ecx; ebp &= (1 << ecx); ebp = ebp >> ecx; //keyTable[edx] = ((ebp & 1) << eax) | (~(1 << eax) & keyTable[edx]); ckt = (keyTable + edx); ckt_temp = *ckt; *ckt = ebp & 1; *ckt = *ckt << eax; *ckt |= (~(1 << eax) & ckt_temp); esi += 0xB; if (esi >= 120) esi -= 120; } } inline char CDKeyDecoder::getHexValue(int v) { v &= 0xF; return (v < 10) ? (v + 0x30) : (v + 0x37); } inline int CDKeyDecoder::getNumValue(char c) { c = toupper(c); return (isdigit(c)) ? (c - 0x30) : (c - 0x37); } bncsutil-1.4.5/src/bncsutil/cdkeydecoder.h000066400000000000000000000066031523672167100205730ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * CD-Key Decoder Interface * September 29, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef BNCSUTIL_CDKEYDECODER_H #define BNCSUTIL_CDKEYDECODER_H #include /** * Internal key type constants. */ #define KEY_STARCRAFT 1 #define KEY_DIABLO2 2 #define KEY_WARCRAFT2 2 /* [sic] */ #define KEY_WARCRAFT3 3 MCEXP(CDKeyDecoder) { protected: char* cdkey; int initialized; int keyOK; size_t keyLen; char* keyHash; size_t hashLen; int keyType; unsigned long value1; unsigned long value2; unsigned long product; char* w3value2; int processStarCraftKey(); int processWarCraft2Key(); int processWarCraft3Key(); void decodeKeyTable(int* keyTable); inline char getHexValue(int v); inline int getNumValue(char v); inline void mult(int r, int x, int* a, int dcByte); public: /** * Creates a new CD-key decoder object. * Not really useful unless subclassed. */ CDKeyDecoder(); CDKeyDecoder(const char* cd_key); /** * Creates a new CD-key decoder object, using the specified key. * keyLength should be the length of the key, NOT INCLUDING the * null-terminator. Applications should use isKeyValid after using * this constructor to check the validity of the provided key. */ CDKeyDecoder(const char* cdKey, size_t keyLength); virtual ~CDKeyDecoder(); int isKeyValid(); int getVal2Length(); uint32_t getProduct(); uint32_t getVal1(); uint32_t getVal2(); int getLongVal2(char* out); /** * Calculates the CD-Key hash for use in SID_AUTH_CHECK (0x51) * Returns the length of the generated hash; call getHash and pass * it a character array that is at least this size. Returns 0 on failure. * * Note that clientToken and serverToken will be added to the buffer and * hashed as-is, regardless of system endianness. It is assumed that * the program's extraction of the server token does not change its * endianness, and since the client token is generated by the client, * endianness is not a factor. */ size_t calculateHash(uint32_t clientToken, uint32_t serverToken); /** * Places the calculated CD-key hash in outputBuffer. You must call * calculateHash before getHash. Returns the length of the hash * that was copied to outputBuffer, or 0 on failure. The hash is * not deleted after getHash is run; subsequent calls to getHash * will still function. */ size_t getHash(char* outputBuffer); }; #endif /* BNCSUTIL_CDKEYDECODER_H */ bncsutil-1.4.5/src/bncsutil/checkrevision.cpp000066400000000000000000000353751523672167100213450ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * CheckRevision Implementation * November 12, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #ifdef MOS_WINDOWS #include #else #include #include #include #include #endif #ifndef HIWORD #define HIWORD(l) ((uint16_t) ((l) >> 16)) #endif #ifndef LOWORD #define LOWORD(l) ((uint16_t) ((l) & 0xFFFF)) #endif #ifdef HAVE__SNPRINTF #define snprintf _snprintf #endif // BNCSutil - CheckRevision - GetNumber #define BUCR_GETNUM(ch) (((ch) == 'S') ? 3 : ((ch) - 'A')) // BNCSutil - CheckRevision - IsNumber #define BUCR_ISNUM(ch) (((ch) >= '0') && ((ch) <= '9')) #include #ifdef __cplusplus extern "C" { #endif std::vector checkrevision_seeds; void initialize_checkrevision_seeds() { static bool run = false; if (run) return; run = true; checkrevision_seeds.reserve(8); checkrevision_seeds.push_back(0xE7F4CB62); checkrevision_seeds.push_back(0xF6A14FFC); checkrevision_seeds.push_back(0xAA5504AF); checkrevision_seeds.push_back(0x871FCDC2); checkrevision_seeds.push_back(0x11BF6A18); checkrevision_seeds.push_back(0xC57292E6); checkrevision_seeds.push_back(0x7927D27E); checkrevision_seeds.push_back(0x2FEC8733); } MEXP(long) get_mpq_seed(int mpq_number) { if (((size_t) mpq_number) >= checkrevision_seeds.size()) { //bncsutil_debug_message_a("error: no known revision check seed for " // "MPQ#%u", mpq_number); return 0; } return checkrevision_seeds[mpq_number]; } MEXP(long) set_mpq_seed(int mpq_number, long new_seed) { long ret; if (((size_t) mpq_number) >= checkrevision_seeds.size()) { ret = 0; checkrevision_seeds.reserve((size_t) mpq_number); } else { ret = checkrevision_seeds[mpq_number]; } checkrevision_seeds[mpq_number] = new_seed; return ret; } MEXP(int) extractMPQNumber(const char* mpqName) { const char* n; int mpqNum; if (mpqName == NULL) return -1; if ((n = (const char*) std::strchr(mpqName, '.')) == NULL) return -1; // extract int value of version number mpqNum = atoi(n - 1); return mpqNum; } const char* get_basename(const char* file_name) { const char* base; for (base = (file_name + strlen(file_name)); base >= file_name; base--) { if (*base == '\\' || *base == '/') break; } return ++base; } MEXP(int) checkRevision(const char* formula, const char* files[], int numFiles, int mpqNumber, unsigned long* checksum) { uint64_t values[4]; long ovd[4], ovs1[4], ovs2[4]; char ops[4]; const char* token; int curFormula = 0; file_t f; uint8_t* file_buffer; uint32_t* dwBuf; uint32_t* current; size_t seed_count; #if DEBUG int i; bncsutil_debug_message_a("checkRevision(\"%s\", {", formula); for (i = 0; i < numFiles; i++) { bncsutil_debug_message_a("\t\"%s\",", files[i]); } bncsutil_debug_message_a("}, %d, %d, %p);", numFiles, mpqNumber, checksum); #endif if (!formula || !files || numFiles == 0 || mpqNumber < 0 || !checksum) { //bncsutil_debug_message("error: checkRevision() parameter sanity check " // "failed"); return 0; } seed_count = checkrevision_seeds.size(); if (seed_count == 0) { initialize_checkrevision_seeds(); seed_count = checkrevision_seeds.size(); } if (seed_count <= (size_t) mpqNumber) { //bncsutil_debug_message_a("error: no revision check seed value defined " // "for MPQ number %d", mpqNumber); return 0; } token = formula; while (token && *token) { if (*(token + 1) == '=') { int variable = BUCR_GETNUM(*token); if (variable < 0 || variable > 3) { //bncsutil_debug_message_a("error: Unknown revision check formula" // " variable %c", *token); return 0; } token += 2; // skip over equals sign if (BUCR_ISNUM(*token)) { values[variable] = ATOL64(token); } else { if (curFormula > 3) { // more than 4 operations? bloody hell. //bncsutil_debug_message("error: Revision check formula" // " contains more than 4 operations; unsupported."); return 0; } ovd[curFormula] = variable; ovs1[curFormula] = BUCR_GETNUM(*token); ops[curFormula] = *(token + 1); ovs2[curFormula] = BUCR_GETNUM(*(token + 2)); curFormula++; } } for (; *token != 0; token++) { if (*token == ' ') { token++; break; } } } // Actual hashing (yay!) // "hash A by the hashcode" values[0] ^= checkrevision_seeds[mpqNumber]; for (int i = 0; i < numFiles; i++) { size_t file_len, remainder, buffer_size; f = file_open(files[i], FILE_READ); if (!f) { //bncsutil_debug_message_a("error: Failed to open file %s", // files[i]); return 0; } file_len = file_size(f); remainder = file_len % 1024; file_buffer = (uint8_t*) file_map(f, file_len, 0); if (!file_buffer) { file_close(f); //bncsutil_debug_message_a("error: Failed to map file %s into memory", // files[i]); return 0; } if (remainder == 0) { // Mapped buffer may be used directly, without padding. dwBuf = (uint32_t*) file_buffer; buffer_size = file_len; } else { // Must be padded to nearest KB. size_t extra = 1024 - remainder; uint8_t pad = (uint8_t) 0xFF; uint8_t* pad_dest; buffer_size = file_len + extra; dwBuf = (uint32_t*) malloc(buffer_size); if (!dwBuf) { //bncsutil_debug_message_a("error: Failed to allocate %d bytes " // "of memory as a temporary buffer", buffer_size); file_unmap(f, file_buffer); file_close(f); return 0; } memcpy(dwBuf, file_buffer, file_len); file_unmap(f, file_buffer); file_buffer = (uint8_t*) 0; pad_dest = ((uint8_t*) dwBuf) + file_len; for (size_t j = file_len; j < buffer_size; j++) { *pad_dest++ = pad--; } } current = dwBuf; for (size_t j = 0; j < buffer_size; j += 4) { values[3] = LSB4(*(current++)); for (int k = 0; k < curFormula; k++) { switch (ops[k]) { case '+': values[ovd[k]] = values[ovs1[k]] + values[ovs2[k]]; break; case '-': values[ovd[k]] = values[ovs1[k]] - values[ovs2[k]]; break; case '^': values[ovd[k]] = values[ovs1[k]] ^ values[ovs2[k]]; break; case '*': // well, you never know values[ovd[k]] = values[ovs1[k]] * values[ovs2[k]]; break; case '/': // well, you never know if (values[ovs2[k]] == 0) return 0; values[ovd[k]] = values[ovs1[k]] / values[ovs2[k]]; break; default: // unrecognized operation // shit file_unmap(f, dwBuf); file_close(f); return 0; } } } if (file_buffer) file_unmap(f, file_buffer); else if (dwBuf && file_buffer == 0) free(dwBuf); // padded buffer file_close(f); } *checksum = (unsigned long) LSB4(values[2]); #if DEBUG bncsutil_debug_message_a("\tChecksum = %lu", *checksum); #endif return 1; } MEXP(int) checkRevisionFlat(const char* valueString, const char* file1, const char* file2, const char* file3, int mpqNumber, unsigned long* checksum) { const char* files[] = {file1, file2, file3}; return checkRevision(valueString, files, 3, mpqNumber, checksum); } MEXP(int) getExeInfo(const char* file_name, char* exe_info, size_t exe_info_size, uint32_t* version, int platform) { const char* base = (char*) 0; unsigned long file_size; FILE* f = (FILE*) 0; int ret; #ifdef MOS_WINDOWS HANDLE hFile; FILETIME ft; SYSTEMTIME st; LPBYTE buf; VS_FIXEDFILEINFO* ffi; DWORD infoSize, bytesRead; #else cm_pe_t pe; cm_pe_resdir_t* root; cm_pe_resdir_t* dir; cm_pe_version_t ffi; size_t i; struct stat st; struct tm* time; #endif if (!file_name || !exe_info || !exe_info_size || !version) return 0; base = get_basename(file_name); switch (platform) { case BNCSUTIL_PLATFORM_X86: #ifdef MOS_WINDOWS infoSize = GetFileVersionInfoSize(file_name, &bytesRead); if (infoSize == 0) return 0; buf = (LPBYTE) VirtualAlloc(NULL, infoSize, MEM_COMMIT, PAGE_READWRITE); if (buf == NULL) return 0; if (GetFileVersionInfo(file_name, NULL, infoSize, buf) == FALSE) return 0; if (!VerQueryValue(buf, "\\", (LPVOID*) &ffi, (PUINT) &infoSize)) return 0; *version = ((HIWORD(ffi->dwProductVersionMS) & 0xFF) << 24) | ((LOWORD(ffi->dwProductVersionMS) & 0xFF) << 16) | ((HIWORD(ffi->dwProductVersionLS) & 0xFF) << 8) | (LOWORD(ffi->dwProductVersionLS) & 0xFF); #if DEBUG bncsutil_debug_message_a("%s version = %d.%d.%d.%d (0x%08X)", base, (HIWORD(ffi->dwProductVersionMS) & 0xFF), (LOWORD(ffi->dwProductVersionMS) & 0xFF), (HIWORD(ffi->dwProductVersionLS) & 0xFF), (LOWORD(ffi->dwProductVersionLS) & 0xFF), *version); #endif VirtualFree(buf, 0lu, MEM_RELEASE); #else pe = cm_pe_load(file_name); if (!pe) return 0; root = cm_pe_load_resources(pe); if (!root) { cm_pe_unload(pe); return 0; } for (i = 0; i < root->subdir_count; i++) { dir = (root->subdirs + i); if (dir->name == 16) { if (!cm_pe_fixed_version(pe, dir->subdirs->resources, &ffi)) { cm_pe_unload_resources(root); cm_pe_unload(pe); return 0; } break; } } *version = ((HIWORD(ffi.dwProductVersionMS) & 0xFF) << 24) | ((LOWORD(ffi.dwProductVersionMS) & 0xFF) << 16) | ((HIWORD(ffi.dwProductVersionLS) & 0xFF) << 8) | (LOWORD(ffi.dwProductVersionLS) & 0xFF); #if DEBUG bncsutil_debug_message_a("%s version = %d.%d.%d.%d (0x%08X)", base, (HIWORD(ffi.dwProductVersionMS) & 0xFF), (LOWORD(ffi.dwProductVersionMS) & 0xFF), (HIWORD(ffi.dwProductVersionLS) & 0xFF), (LOWORD(ffi.dwProductVersionLS) & 0xFF), *version); #endif cm_pe_unload_resources(root); cm_pe_unload(pe); #endif break; case BNCSUTIL_PLATFORM_MAC: case BNCSUTIL_PLATFORM_OSX: f = fopen(file_name, "r"); if (!f) return 0; if (fseek(f, -4, SEEK_END) != 0) { fclose(f); return 0; } if (fread(version, 4, 1, f) != 1) { fclose(f); return 0; } #ifdef MOS_WINDOWS fclose(f); #endif } #ifdef MOS_WINDOWS hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return 0; file_size = GetFileSize(hFile, NULL); if (!GetFileTime(hFile, &ft, NULL, NULL)) { CloseHandle(hFile); return 0; } if (!FileTimeToSystemTime(&ft, &st)) { CloseHandle(hFile); return 0; } CloseHandle(hFile); ret = snprintf(exe_info, exe_info_size, "%s %02u/%02u/%02u %02u:%02u:%02u %lu", base, st.wMonth, st.wDay, (st.wYear % 100), st.wHour, st.wMinute, st.wSecond, file_size); #else if (!f) f = fopen(file_name, "r"); if (!f) return 0; if (fseek(f, 0, SEEK_END) == -1) { fclose(f); return 0; } file_size = ftell(f); fclose(f); if (stat(file_name, &st) != 0) return 0; time = gmtime(&st.st_mtime); if (!time) return 0; switch (platform) { case BNCSUTIL_PLATFORM_MAC: case BNCSUTIL_PLATFORM_OSX: if (time->tm_year >= 100) // y2k time->tm_year -= 100; break; } ret = (int) snprintf(exe_info, exe_info_size, "%s %02u/%02u/%02u %02u:%02u:%02u %lu", base, (time->tm_mon+1), time->tm_mday, (time->tm_year % 100), time->tm_hour, time->tm_min, time->tm_sec, file_size); #endif #if DEBUG bncsutil_debug_message(exe_info); #endif return ret; } #ifdef __cplusplus } // extern "C" #endif bncsutil-1.4.5/src/bncsutil/checkrevision.h000066400000000000000000000061031523672167100207750ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * CheckRevision Interface * November 12, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef BNCSUTIL_CHECKREVISION_H #define BNCSUTIL_CHECKREVISION_H #ifdef __cplusplus #include extern "C" { #endif /** * Platform constants for getExeInfo(). */ #define BNCSUTIL_PLATFORM_X86 1 #define BNCSUTIL_PLATFORM_WINDOWS 1 #define BNCSUTIL_PLATFORM_WIN 1 #define BNCSUTIL_PLATFORM_MAC 2 #define BNCSUTIL_PLATFORM_PPC 2 #define BNCSUTIL_PLATFORM_OSX 3 /** * Reads an MPQ filename (e.g. IX86ver#.mpq), extracts the #, * and returns the int value of that number. Returns -1 on * failure. */ MEXP(int) extractMPQNumber(const char* mpqName); /** * Runs CheckRevision. * First file must be the executable file. */ MEXP(int) checkRevision( const char* valueString, const char* files[], int numFiles, int mpqNumber, unsigned long* checksum ); /** * Alternate form of CheckRevision function. * Really only useful for VB programmers; * VB seems to have trouble passing an array * of strings to a DLL function */ MEXP(int) checkRevisionFlat( const char* valueString, const char* file1, const char* file2, const char* file3, int mpqNumber, unsigned long* checksum ); /** * Retrieves version and date/size information from executable file. * Returns 0 on failure or length of exeInfoString. * If the generated string is longer than the buffer, the needed buffer * length will be returned, but the string will not be copied into * exeInfoString. Applications should check to see if the return value * is greater than the length of the buffer, and increase its size if * necessary. */ MEXP(int) getExeInfo(const char* file_name, char* exe_info, size_t exe_info_size, uint32_t* version, int platform); /** * Gets the seed value for the given MPQ file. If no seed value for the given * MPQ is registered with BNCSutil, returns 0. */ MEXP(long) get_mpq_seed(int mpq_number); /** * Sets the seed value for the given MPQ file. Returns the old seed value if * there was any, or 0 if this was a new addition. */ MEXP(long) set_mpq_seed(int mpq_number, long new_seed); #ifdef __cplusplus } // extern "C" #endif #endif /* BNCSUTIL_CHECKREVISION_H */ bncsutil-1.4.5/src/bncsutil/decodekey.cpp000066400000000000000000000215631523672167100204370ustar00rootroot00000000000000 /** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * CD-Key Decoder C Wrappers * October 17, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef DECODECDKEY_CPP #define DECODECDKEY_CPP #include #include #include #ifdef MOS_WINDOWS #include #else #include #include #endif #include #ifdef __cplusplus extern "C" { #endif #define DEFAULT_DECODERS_SIZE 4 #define MUTEX_TIMEOUT_MS 6000L #ifndef CLOCKS_PER_SEC # ifdef CLK_TCK # define CLOCKS_PER_SEC CLK_TCK # else # define CLOCKS_PER_SEC 1000000 # endif #endif CDKeyDecoder** decoders; unsigned int numDecoders = 0; unsigned int sizeDecoders = 0; #ifdef MOS_WINDOWS // HANDLE mutex; CRITICAL_SECTION kd_control; #else pthread_mutex_t mutex; #endif int kd_lock_decoders() { #ifdef MOS_WINDOWS /* DWORD dwWaitResult; dwWaitResult = WaitForSingleObject(mutex, MUTEX_TIMEOUT_MS); switch (dwWaitResult) { case WAIT_OBJECT_0: // success break; case WAIT_TIMEOUT: return 0; break; case WAIT_ABANDONED: // weird, but should be OK break; default: return 0; break; }*/ EnterCriticalSection(&kd_control); #else int err = 0; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; struct timespec wait_time = {0, MUTEX_TIMEOUT_MS * 1000}; err = pthread_cond_timedwait(&cond, &mutex, &wait_time); switch (err) { case 0: // success break; default: // error return 0; } #endif return 1; } #ifdef MOS_WINDOWS #define kd_unlock_decoders() LeaveCriticalSection(&kd_control) #else #define kd_unlock_decoders() pthread_mutex_unlock(&mutex) #endif MEXP(int) kd_quick(const char* cd_key, uint32_t client_token, uint32_t server_token, uint32_t* public_value, uint32_t* product, char* hash_buffer, size_t buffer_len) { CDKeyDecoder kd(cd_key, strlen(cd_key)); size_t hash_len; if (kd.isKeyValid() == 0) return 0; *public_value = kd.getVal1(); *product = kd.getProduct(); hash_len = kd.calculateHash(client_token, server_token); if ((hash_len == 0U) || hash_len > buffer_len) return 0; kd.getHash(hash_buffer); return 1; } MEXP(int) kd_init() { static int has_run = 0; if (has_run) return 1; #ifdef MOS_WINDOWS /*mutex = CreateMutex(NULL, FALSE, NULL); if (mutex == NULL) return 0;*/ InitializeCriticalSection(&kd_control); #else if (pthread_mutex_init(&mutex, NULL) != 0) return 0; #endif numDecoders = 0; sizeDecoders = 0; decoders = (CDKeyDecoder**) 0; has_run = 1; #if DEBUG bncsutil_debug_message("Initialized key decoding C API."); #endif return 1; } unsigned int kd_findAvailable() { unsigned int i; CDKeyDecoder** d; d = decoders; for (i = 0; i < sizeDecoders; i++) { if (*d == (CDKeyDecoder*) 0) return i; d++; } // no room available, must expand decoders = (CDKeyDecoder**) realloc(decoders, sizeof(CDKeyDecoder*) * (sizeDecoders + DEFAULT_DECODERS_SIZE)); if (!decoders) return (unsigned int) -1; memset(decoders + sizeDecoders, 0, sizeof(CDKeyDecoder*) * DEFAULT_DECODERS_SIZE); // zero new memory i = sizeDecoders; sizeDecoders += DEFAULT_DECODERS_SIZE; return i; } MEXP(int) kd_create(const char* cdkey, const int keyLength) { unsigned int i; CDKeyDecoder** d; static int dcs_initialized = 0; if (dcs_initialized == 0) { if (kd_init() == 0) return -1; dcs_initialized = 1; } if (kd_lock_decoders() == 0) return -1; i = kd_findAvailable(); if (i == (unsigned int) -1) return -1; d = (decoders + i); *d = new CDKeyDecoder(cdkey, keyLength); if (!(**d).isKeyValid()) { delete *d; *d = (CDKeyDecoder*) 0; return -1; } numDecoders++; kd_unlock_decoders(); return (int) i; } /* MEXP(int) kd_create(char* cdkey, int keyLength) { if (!kd_lock_decoders()) return -1; CDKeyDecoder* d; unsigned int i; if (numDecoders >= sizeDecoders) { CDKeyDecoder** temp = new CDKeyDecoder*[sizeDecoders]; for (unsigned int j = 0; j < sizeDecoders; j++) { temp[j] = decoders[j]; } delete [] decoders; decoders = new CDKeyDecoder*[sizeDecoders + DEFAULT_DECODERS_SIZE]; for (unsigned int j = 0; j < sizeDecoders; j++) { decoders[j] = temp[j]; } delete [] temp; sizeDecoders += DEFAULT_DECODERS_SIZE; } i = numDecoders++; decoders[i] = new CDKeyDecoder(cdkey, keyLength); d = decoders[i]; if (!d->isKeyValid()) { delete decoders[i]; return -1; } kd_unlock_decoders(); d = NULL; return (int) i; }*/ MEXP(int) kd_free(const int decoder) { CDKeyDecoder* d; if (kd_lock_decoders() == 0) return 0; if ((unsigned int) decoder >= sizeDecoders) return 0; d = *(decoders + decoder); if (!d) return 0; delete d; *(decoders + decoder) = (CDKeyDecoder*) 0; kd_unlock_decoders(); return 1; } MEXP(int) kd_val2Length(int decoder) { CDKeyDecoder* d; int value; if (kd_lock_decoders() == 0) return -1; if ((unsigned int) decoder >= sizeDecoders) return -1; d = *(decoders + decoder); if (!d) return -1; value = d->getVal2Length(); kd_unlock_decoders(); return value; } MEXP(int) kd_product(int decoder) { CDKeyDecoder* d; int value; if (kd_lock_decoders() == 0) return -1; if ((unsigned int) decoder >= sizeDecoders) return -1; d = *(decoders + decoder); if (!d) return -1; value = d->getProduct(); kd_unlock_decoders(); return value; } MEXP(int) kd_val1(const int decoder) { CDKeyDecoder* d; int value; if (kd_lock_decoders() == 0) return -1; if ((unsigned int) decoder >= sizeDecoders) return -1; d = *(decoders + decoder); if (!d) return -1; value = d->getVal1(); kd_unlock_decoders(); return value; } MEXP(int) kd_val2(int decoder) { CDKeyDecoder* d; int value; if (kd_lock_decoders() == 0) return -1; if ((unsigned int) decoder >= sizeDecoders) return -1; d = *(decoders + decoder); if (!d) return -1; value = d->getVal2(); kd_unlock_decoders(); return value; } MEXP(int) kd_longVal2(const int decoder, char* out) { CDKeyDecoder* d; int value; if (kd_lock_decoders() == 0) return -1; if ((unsigned int) decoder >= sizeDecoders) return -1; d = *(decoders + decoder); if (!d) return -1; value = d->getLongVal2(out); kd_unlock_decoders(); return value; } MEXP(int) kd_calculateHash(const int decoder, const uint32_t clientToken, const uint32_t serverToken) { CDKeyDecoder* d; int value; if (kd_lock_decoders() == 0) return -1; if ((unsigned int) decoder >= sizeDecoders) return -1; d = *(decoders + decoder); if (!d) return -1; value = (int) d->calculateHash(clientToken, serverToken); kd_unlock_decoders(); return value; } MEXP(int) kd_getHash(const int decoder, char* out) { CDKeyDecoder* d; int value; if (kd_lock_decoders() == 0) return -1; if ((unsigned int) decoder >= sizeDecoders) return -1; d = *(decoders + decoder); if (!d) return -1; value = (int) d->getHash(out); kd_unlock_decoders(); return value; } MEXP(int) kd_isValid(const int decoder) { CDKeyDecoder* d; int value; if (kd_lock_decoders() == 0) return -1; if ((unsigned int) decoder >= sizeDecoders) return -1; d = *(decoders + decoder); if (!d) return -1; value = d->isKeyValid(); kd_unlock_decoders(); return value; } #ifdef __cplusplus } #endif #endif /* DECODECDKEY_CPP -- note to self: why is this here? */ bncsutil-1.4.5/src/bncsutil/decodekey.h000066400000000000000000000066271523672167100201100ustar00rootroot00000000000000 /** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * CD-Key Decoder C Wrappers * October 17, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef DECODEKEY_H #define DECODEKEY_H #include #ifdef __cplusplus extern "C" { #endif /** * Decodes a CD-key, retrieves its relevant values, and calculates a hash * suitable for SID_AUTH_CHECK (0x51) in one function call. Returns 1 on * success or 0 on failure. A call to kd_init does NOT need to be made before * calling this function. Available since BNCSutil 1.1.0. */ MEXP(int) kd_quick(const char* cd_key, uint32_t client_token, uint32_t server_token, uint32_t* public_value, uint32_t* product, char* hash_buffer, size_t buffer_len); /** * Initializes the CD-key decoding C wrappers. * Returns 1 on success or 0 on failure. */ MEXP(int) kd_init(); /** * Creates a new CD-key decoder. Returns its ID on success * or -1 on failure or invalid CD-key. */ MEXP(int) kd_create(const char* cdkey, int keyLength); /** * Frees the specified CD-key decoder. * Returns 1 on success or 0 on failure. */ MEXP(int) kd_free(int decoder); /** * Gets the length of the private value for the given decoder. * Returns the length or 0 on failure. */ MEXP(int) kd_val2Length(int decoder); /** * Gets the product value for the given decoder. * Returns the length or 0 on failure. */ MEXP(int) kd_product(int decoder); /** * Gets the public value for the given decoder. * Returns the length or 0 on failure. */ MEXP(int) kd_val1(int decoder); /** * Gets the rivate value for the given decoder. * Only use this function if kd_val2Length <= 4. * Returns the length or 0 on failure. */ MEXP(int) kd_val2(int decoder); /** * Gets the length of the private value for the given decoder. * Only use this function if kd_val2Length > 4. * Returns the length or 0 on failure. */ MEXP(int) kd_longVal2(int decoder, char* out); /** * Calculates the hash of the key values for SID_AUTH_CHECK (0x51). * Returns the hash length or 0 on failure. */ MEXP(int) kd_calculateHash(int decoder, uint32_t clientToken, uint32_t serverToken); /** * Places the key hash in "out". The "out" buffer must be * at least the length returned from kd_calculateHash. * Returns the hash length or 0 on failure. */ MEXP(int) kd_getHash(int decoder, char* out); /** * [!] kd_isValid has been deprecated. kd_create checks * whether the key was valid before returning, and * destroys the decoder and returns an error code * if it was invalid. */ MEXP(int) kd_isValid(int decoder); #ifdef __cplusplus } // extern "C" #endif #endif // DECODEKEY_H bncsutil-1.4.5/src/bncsutil/file.cpp000066400000000000000000000157521523672167100174250ustar00rootroot00000000000000#include #include #include #include #ifdef MOS_WINDOWS #define WIN32_LEAN_AND_MEAN #define BWIN 1 #include typedef std::map mapping_map; #else #define BWIN 0 #include #include #include typedef std::map mapping_map; #endif struct _file { #if BWIN HANDLE f; #else FILE* f; #endif const char* filename; mapping_map mappings; }; #ifdef __cplusplus extern "C" { #endif #if BWIN file_t file_open(const char* filename, unsigned int mode) { file_t data; HANDLE file; DWORD access; DWORD share_mode; DWORD open_mode; //const char* sys_err; size_t filename_buf_len; if (mode & FILE_READ) { access = GENERIC_READ; share_mode = FILE_SHARE_READ; open_mode = OPEN_EXISTING; } else if (mode & FILE_WRITE) { access = GENERIC_WRITE; share_mode = 0; open_mode = CREATE_ALWAYS; } file = CreateFile(filename, access, share_mode, NULL, open_mode, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) { //sys_err = sys_error_msg(); //bncsutil_debug_message_a("Cannot open file \"%s\"; %s", filename, sys_err); //free_sys_err_msg(sys_err); return ((file_t) 0); } try { data = new _file; } catch (const std::bad_alloc&) { //bncsutil_debug_message_a("Failed to allocate %u bytes to hold file structure.", sizeof(struct _file)); CloseHandle(file); return (file_t) 0; } filename_buf_len = strlen(filename) + 1; data->filename = (const char*) malloc(filename_buf_len); if (!data->filename) { //bncsutil_debug_message_a("Failed to allocate %u bytes to hold filename.", filename_buf_len); CloseHandle(file); delete data; return (file_t) 0; } strcpy_s((char*) data->filename, filename_buf_len, filename); data->f = file; return data; } void file_close(file_t file) { mapping_map::iterator it; if (!file) { //bncsutil_debug_message_a("error: null pointer given to file_close"); return; } for (it = file->mappings.begin(); it != file->mappings.end(); it++) { UnmapViewOfFile((*it).first); CloseHandle((*it).second); } CloseHandle((HANDLE) file->f); free((void*) file->filename); delete file; } size_t file_read(file_t file, void* ptr, size_t size, size_t count) { DWORD bytes_read; if (!ReadFile(file->f, ptr, (DWORD) (size * count), &bytes_read, NULL)) { return (size_t) 0; } return (size_t) bytes_read; } size_t file_write(file_t file, const void* ptr, size_t size, size_t count) { DWORD bytes_written; if (!WriteFile(file->f, ptr, (DWORD) (size * count), &bytes_written, NULL)) return (size_t) 0; return (size_t) bytes_written; } size_t file_size(file_t file) { return (size_t) GetFileSize(file->f, (LPDWORD) 0); } void* file_map(file_t file, size_t len, off_t offset) { HANDLE mapping = CreateFileMapping((HANDLE) file->f, NULL, PAGE_READONLY, 0, 0, NULL); void* base; //const char* err; if (!mapping) { //err = sys_error_msg(); //bncsutil_debug_message_a("Failed to create file mapping for \"%s\": %s", file->filename, err); //free_sys_err_msg(err); return (void*) 0; } base = MapViewOfFile(mapping, FILE_MAP_READ, 0, (DWORD) offset, len); if (!base) { CloseHandle(mapping); //err = sys_error_msg(); //bncsutil_debug_message_a("Failed to map %u bytes of \"%s\" starting at %u: %s", len, file->filename, offset, err); //free_sys_err_msg(err); return (void*) 0; } file->mappings[base] = mapping; return base; } void file_unmap(file_t file, const void* base) { mapping_map::iterator item = file->mappings.find(base); HANDLE mapping; if (item == file->mappings.end()) { //bncsutil_debug_message_a("warning: failed to unmap the block starting at %p from %s; unknown block.", base, file->filename); return; } mapping = (*item).second; UnmapViewOfFile(base); CloseHandle(mapping); file->mappings.erase(item); } #else file_t file_open(const char* filename, const unsigned int mode_flags) { char mode[] = "rb"; file_t data; FILE* f; size_t filename_buf_len; //const char* err; if (mode_flags & FILE_WRITE) mode[0] = 'w'; f = fopen(filename, mode); if (!f) { return (file_t) 0; } try { data = new _file; } catch (const std::bad_alloc&) { //bncsutil_debug_message_a("Failed to allocate %u bytes to hold file structure.", sizeof(struct _file)); fclose(f); return (file_t) 0; } filename_buf_len = strlen(filename) + 1; data->filename = (const char*) malloc(filename_buf_len); if (!data->filename) { //err = sys_error_msg(); //bncsutil_debug_message_a("Failed to allocate %u bytes to hold filename; %s", filename_buf_len); //free_sys_err_msg(err); fclose(f); delete data; return (file_t) 0; } strcpy((char*) data->filename, filename); data->f = f; return data; } void file_close(file_t file) { mapping_map::iterator it; if (!file) { //bncsutil_debug_message("error: null pointer given to file_close"); return; } for (it = file->mappings.begin(); it != file->mappings.end(); it++) { munmap((void*) (*it).first, (*it).second); } fclose(file->f); delete file; } size_t file_read(file_t file, void* ptr, size_t size, size_t count) { return fread(ptr, size, count, file->f); } size_t file_write(file_t file, const void* ptr, size_t size, size_t count) { return fwrite(ptr, size, count, file->f); } size_t file_size(file_t file) { long cur_pos = ftell(file->f); size_t size_of_file; fseek(file->f, 0, SEEK_END); size_of_file = (size_t) ftell(file->f); fseek(file->f, cur_pos, SEEK_SET); return size_of_file; } void* file_map(file_t file, const size_t len, const off_t offset) { const int fd = fileno(file->f); void* base = mmap((void*) 0, len, PROT_READ, MAP_SHARED, fd, offset); //const char* err; if (!base) { //err = sys_error_msg(); //bncsutil_debug_message_a("error: failed to map %u bytes of %s starting at %u into memory; %s", len, file->filename, offset, err); //free_sys_err_msg(err); return (void*) 0; } file->mappings[base] = len; return base; } void file_unmap(file_t file, const void* mapping) { mapping_map::iterator item = file->mappings.find(mapping); size_t len; if (item == file->mappings.end()) { //bncsutil_debug_message_a("warning: failed to unmap the block starting at %p from %s; unknown block.", base, file->filename); return; } len = (*item).second; munmap((void*) mapping, len); file->mappings.erase(item); } #endif #ifdef __cplusplus } #endif bncsutil-1.4.5/src/bncsutil/file.h000066400000000000000000000031231523672167100170570ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * File Access * February 12, 2006 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef _FILE_H_INCLUDED_ #define _FILE_H_INCLUDED_ 1 #ifdef MOS_WINDOWS typedef long off_t; #else #include #endif #ifdef __cplusplus extern "C" { #endif typedef struct _file* file_t; #define FILE_READ (0x01) #define FILE_WRITE (0x02) file_t file_open(const char* filename, unsigned int mode_flags); void file_close(file_t file); size_t file_read(file_t file, void* ptr, size_t size, size_t count); size_t file_write(file_t file, const void* ptr, size_t size, size_t count); size_t file_size(file_t file); void* file_map(file_t file, size_t len, off_t offset); void file_unmap(file_t file, const void* mapping); #ifdef __cplusplus } #endif #endif /* _FILE_H_INCLUDED_ */ bncsutil-1.4.5/src/bncsutil/keytables.h000066400000000000000000000165651523672167100201410ustar00rootroot00000000000000 /** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * WarCraft II/Diablo II and WarCraft III Decoding Tables * October 2, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef BNCSUTIL_KEYTABLES_H #define BNCSUTIL_KEYTABLES_H #ifdef __cplusplus extern "C" { #endif const unsigned char w2Map[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x01, 0xFF, 0x02, 0x03, 0x04, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0xFF, 0x0D, 0x0E, 0xFF, 0x0F, 0x10, 0xFF, 0x11, 0xFF, 0x12, 0xFF, 0x13, 0xFF, 0x14, 0x15, 0x16, 0xFF, 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0xFF, 0x0D, 0x0E, 0xFF, 0x0F, 0x10, 0xFF, 0x11, 0xFF, 0x12, 0xFF, 0x13, 0xFF, 0x14, 0x15, 0x16, 0xFF, 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; const unsigned char w3KeyMap[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x01, 0xFF, 0x02, 0x03, 0x04, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0xFF, 0x0D, 0x0E, 0xFF, 0x0F, 0x10, 0xFF, 0x11, 0xFF, 0x12, 0xFF, 0x13, 0xFF, 0x14, 0x15, 0x16, 0x17, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0xFF, 0x0D, 0x0E, 0xFF, 0x0F, 0x10, 0xFF, 0x11, 0xFF, 0x12, 0xFF, 0x13, 0xFF, 0x14, 0x15, 0x16, 0x17, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; const unsigned char w3TranslateMap[] = { 0x09, 0x04, 0x07, 0x0F, 0x0D, 0x0A, 0x03, 0x0B, 0x01, 0x02, 0x0C, 0x08, 0x06, 0x0E, 0x05, 0x00, 0x09, 0x0B, 0x05, 0x04, 0x08, 0x0F, 0x01, 0x0E, 0x07, 0x00, 0x03, 0x02, 0x0A, 0x06, 0x0D, 0x0C, 0x0C, 0x0E, 0x01, 0x04, 0x09, 0x0F, 0x0A, 0x0B, 0x0D, 0x06, 0x00, 0x08, 0x07, 0x02, 0x05, 0x03, 0x0B, 0x02, 0x05, 0x0E, 0x0D, 0x03, 0x09, 0x00, 0x01, 0x0F, 0x07, 0x0C, 0x0A, 0x06, 0x04, 0x08, 0x06, 0x02, 0x04, 0x05, 0x0B, 0x08, 0x0C, 0x0E, 0x0D, 0x0F, 0x07, 0x01, 0x0A, 0x00, 0x03, 0x09, 0x05, 0x04, 0x0E, 0x0C, 0x07, 0x06, 0x0D, 0x0A, 0x0F, 0x02, 0x09, 0x01, 0x00, 0x0B, 0x08, 0x03, 0x0C, 0x07, 0x08, 0x0F, 0x0B, 0x00, 0x05, 0x09, 0x0D, 0x0A, 0x06, 0x0E, 0x02, 0x04, 0x03, 0x01, 0x03, 0x0A, 0x0E, 0x08, 0x01, 0x0B, 0x05, 0x04, 0x02, 0x0F, 0x0D, 0x0C, 0x06, 0x07, 0x09, 0x00, 0x0C, 0x0D, 0x01, 0x0F, 0x08, 0x0E, 0x05, 0x0B, 0x03, 0x0A, 0x09, 0x00, 0x07, 0x02, 0x04, 0x06, 0x0D, 0x0A, 0x07, 0x0E, 0x01, 0x06, 0x0B, 0x08, 0x0F, 0x0C, 0x05, 0x02, 0x03, 0x00, 0x04, 0x09, 0x03, 0x0E, 0x07, 0x05, 0x0B, 0x0F, 0x08, 0x0C, 0x01, 0x0A, 0x04, 0x0D, 0x00, 0x06, 0x09, 0x02, 0x0B, 0x06, 0x09, 0x04, 0x01, 0x08, 0x0A, 0x0D, 0x07, 0x0E, 0x00, 0x0C, 0x0F, 0x02, 0x03, 0x05, 0x0C, 0x07, 0x08, 0x0D, 0x03, 0x0B, 0x00, 0x0E, 0x06, 0x0F, 0x09, 0x04, 0x0A, 0x01, 0x05, 0x02, 0x0C, 0x06, 0x0D, 0x09, 0x0B, 0x00, 0x01, 0x02, 0x0F, 0x07, 0x03, 0x04, 0x0A, 0x0E, 0x08, 0x05, 0x03, 0x06, 0x01, 0x05, 0x0B, 0x0C, 0x08, 0x00, 0x0F, 0x0E, 0x09, 0x04, 0x07, 0x0A, 0x0D, 0x02, 0x0A, 0x07, 0x0B, 0x0F, 0x02, 0x08, 0x00, 0x0D, 0x0E, 0x0C, 0x01, 0x06, 0x09, 0x03, 0x05, 0x04, 0x0A, 0x0B, 0x0D, 0x04, 0x03, 0x08, 0x05, 0x09, 0x01, 0x00, 0x0F, 0x0C, 0x07, 0x0E, 0x02, 0x06, 0x0B, 0x04, 0x0D, 0x0F, 0x01, 0x06, 0x03, 0x0E, 0x07, 0x0A, 0x0C, 0x08, 0x09, 0x02, 0x05, 0x00, 0x09, 0x06, 0x07, 0x00, 0x01, 0x0A, 0x0D, 0x02, 0x03, 0x0E, 0x0F, 0x0C, 0x05, 0x0B, 0x04, 0x08, 0x0D, 0x0E, 0x05, 0x06, 0x01, 0x09, 0x08, 0x0C, 0x02, 0x0F, 0x03, 0x07, 0x0B, 0x04, 0x00, 0x0A, 0x09, 0x0F, 0x04, 0x00, 0x01, 0x06, 0x0A, 0x0E, 0x02, 0x03, 0x07, 0x0D, 0x05, 0x0B, 0x08, 0x0C, 0x03, 0x0E, 0x01, 0x0A, 0x02, 0x0C, 0x08, 0x04, 0x0B, 0x07, 0x0D, 0x00, 0x0F, 0x06, 0x09, 0x05, 0x07, 0x02, 0x0C, 0x06, 0x0A, 0x08, 0x0B, 0x00, 0x0F, 0x04, 0x03, 0x0E, 0x09, 0x01, 0x0D, 0x05, 0x0C, 0x04, 0x05, 0x09, 0x0A, 0x02, 0x08, 0x0D, 0x03, 0x0F, 0x01, 0x0E, 0x06, 0x07, 0x0B, 0x00, 0x0A, 0x08, 0x0E, 0x0D, 0x09, 0x0F, 0x03, 0x00, 0x04, 0x06, 0x01, 0x0C, 0x07, 0x0B, 0x02, 0x05, 0x03, 0x0C, 0x04, 0x0A, 0x02, 0x0F, 0x0D, 0x0E, 0x07, 0x00, 0x05, 0x08, 0x01, 0x06, 0x0B, 0x09, 0x0A, 0x0C, 0x01, 0x00, 0x09, 0x0E, 0x0D, 0x0B, 0x03, 0x07, 0x0F, 0x08, 0x05, 0x02, 0x04, 0x06, 0x0E, 0x0A, 0x01, 0x08, 0x07, 0x06, 0x05, 0x0C, 0x02, 0x0F, 0x00, 0x0D, 0x03, 0x0B, 0x04, 0x09, 0x03, 0x08, 0x0E, 0x00, 0x07, 0x09, 0x0F, 0x0C, 0x01, 0x06, 0x0D, 0x02, 0x05, 0x0A, 0x0B, 0x04, 0x03, 0x0A, 0x0C, 0x04, 0x0D, 0x0B, 0x09, 0x0E, 0x0F, 0x06, 0x01, 0x07, 0x02, 0x00, 0x05, 0x08 }; #ifdef __cplusplus } // extern "C" #endif #endif /* BNCSUTIL_KEYTABLES_H */ bncsutil-1.4.5/src/bncsutil/libinfo.cpp000066400000000000000000000032371523672167100201230ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Library Information * November 16, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #include #include #include MEXP(unsigned long) bncsutil_getVersion() { return BNCSUTIL_VERSION; } MEXP(int) bncsutil_getVersionString(char* outBuf) { unsigned long major, minor, rev, ver; int printed; ver = BNCSUTIL_VERSION; // major major = (unsigned long) (BNCSUTIL_VERSION / 10000); if (major > 99 || major < 0) return 0; // minor ver -= (major * 10000); minor = (unsigned long) (ver / 100); if (minor > 99 || minor < 0) return 0; // revision ver -= (minor * 100); rev = ver; if (rev > 99 || rev < 0) return 0; printed = std::sprintf(outBuf, "%lu.%lu.%lu", major, minor, rev); if (printed < 0) return 0; outBuf[8] = '\0'; return printed; } bncsutil-1.4.5/src/bncsutil/libinfo.h000066400000000000000000000027351523672167100175720ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Library Information * November 16, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef BNCSUTIL_LIBINFO_H #define BNCSUTIL_LIBINFO_H #ifdef __cplusplus extern "C" { #endif // Library Version // Defined as follows, for library version a.b.c: // (a * 10^4) + (b * 10^2) + c // Version 1.2.0: #define BNCSUTIL_VERSION 10300 // Get Version MEXP(unsigned long) bncsutil_getVersion(); // Get Version as String // Copies version into outBuf, returns number of bytes copied (or 0 on fail). // (outBuf should be at least 9 bytes long) MEXP(int) bncsutil_getVersionString(char* outbuf); #ifdef __cplusplus } // extern "C" #endif #endif /* BNCSUTIL_LIBINFO_H */ bncsutil-1.4.5/src/bncsutil/mutil.h000066400000000000000000000131011523672167100172670ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Utility Headers * October 23, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef MUTIL_H #define MUTIL_H #define LITTLEENDIAN 1 #ifdef HAVE_CONFIG_H #include #endif /* Specific-Sized Integers */ #include "mutil_types.h" #ifdef __cplusplus #include #else #include #endif // functions for converting a string to a 64-bit number. #if defined(_MSC_VER) #define ATOL64(x) _atoi64(x) #else #define ATOL64(x) atoll(x) #endif #ifdef _MSC_VER #pragma intrinsic(_lrotl,_lrotr) /* use intrinsic compiler rotations */ #define ROL(x,n) _lrotl((x),(n)) #define ROR(x,n) _lrotr((x),(n)) #else #ifndef ROL #define ROL(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) #endif #ifndef ROR #define ROR(a,b) (((a) >> (b)) | ((a) << 32 - (b))) #endif #endif #if (!defined(MUTIL_CPU_PPC)) #if (defined(__ppc__) || defined(__PPC__) || defined(powerpc) || \ defined(powerpc) || defined(ppc) || defined(_M_MPPC)) #define MUTIL_CPU_PPC 1 #define MUTIL_CPU_X86 0 #else #define MUTIL_CPU_PPC 0 #endif #endif #if (!defined(MUTIL_CPU_X86)) #if (__INTEL__ || defined(__i386__) || defined(i386) || defined(intel) || \ defined(_M_IX86)) #define MUTIL_CPU_X86 1 #ifndef MUTIL_CPU_PPC #define MUTIL_CPU_PPC 0 #endif #else #define MUTIL_CPU_X86 0 #endif #endif #if (!defined(BIGENDIAN)) && (!defined(LITTLEENDIAN)) #if MUTIL_CPU_PPC #define BIGENDIAN 1 #define LITTLEENDIAN 0 #elif MUTIL_CPU_X86 #define LITTLEENDIAN 1 #define BIGENDIAN 0 #else #error Unable to determine byte order, define BIGENDIAN or LITTLEENDIAN. #endif #elif defined(BIGENDIAN) && (!defined(LITTLEENDIAN)) #undef BIGENDIAN #define BIGENDIAN 1 #define LITTLEENDIAN 0 #elif defined(LITTLEENDIAN) && (!defined(BIGENDIAN)) #undef LITTLEENDIAN #define LITTLEENDIAN 1 #define BIGENDIAN 0 #endif #define SWAP2(num) ((((num) >> 8) & 0x00FF) | (((num) << 8) & 0xFF00)) #define SWAP4(num) ((((num) >> 24) & 0x000000FF) | (((num) >> 8) & 0x0000FF00) | (((num) << 8) & 0x00FF0000) | (((num) << 24) & 0xFF000000)) #define SWAP8(x) \ (uint64_t)((((uint64_t)(x) & 0xff) << 56) | \ ((uint64_t)(x) & 0xff00ULL) << 40 | \ ((uint64_t)(x) & 0xff0000ULL) << 24 | \ ((uint64_t)(x) & 0xff000000ULL) << 8 | \ ((uint64_t)(x) & 0xff00000000ULL) >> 8 | \ ((uint64_t)(x) & 0xff0000000000ULL) >> 24 | \ ((uint64_t)(x) & 0xff000000000000ULL) >> 40 | \ ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) /* For those who think in bits */ #define SWAP16 SWAP2 #define SWAP32 SWAP4 #define SWAP64 SWAP8 #if BIGENDIAN #define LSB2(num) SWAP2(num) #define LSB4(num) SWAP4(num) #define MSB2(num) (num) #define MSB4(num) (num) #else /* (little endian) */ #define LSB2(num) (num) #define LSB4(num) (num) #define MSB2(num) SWAP2(num) #define MSB4(num) SWAP4(num) #endif /* (endianness) */ #ifndef MOS_WINDOWS /* attempt automatic Windows detection */ #ifdef _MSC_VER /* Microsoft C++ compiler, has to be windows */ #define MOS_WINDOWS #else #if defined(_WIN) || defined(_WINDOWS) || defined(WINDOWS) || \ defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64) #define MOS_WINDOWS #endif #endif #endif #if !(defined(MUTIL_LIB_BUILD)) && defined(BNCSUTIL_EXPORTS) # define MUTIL_LIB_BUILD #endif /** * MUTIL_LIB_BUILD must be defined when compiling the library itself. * It is set automatically by CMake via target_compile_definitions(). * * When defined (building the .so/.dll): * MEXP marks symbols for export: * Windows - __declspec(dllexport) * Linux - __attribute__((visibility("default"))) (with -fvisibility=hidden) * * When not defined (consumer including the header): * MEXP marks symbols for import: * Windows - __declspec(dllimport) * Linux - extern (no-op; ELF resolves symbols at load time) */ #ifdef MOS_WINDOWS # pragma comment(lib, "Version.lib") # ifdef MUTIL_LIB_BUILD # define MEXP(type) __declspec(dllexport) type __cdecl # define MCEXP(name) class __declspec(dllexport) name # else # define MEXP(type) __declspec(dllimport) type __cdecl # define MCEXP(name) class __declspec(dllimport) name # endif #else # ifdef MUTIL_LIB_BUILD # define MEXP(type) __attribute__((visibility("default"))) type # define MCEXP(name) class __attribute__((visibility("default"))) name # else # define MEXP(type) extern type # define MCEXP(name) class name # endif #endif #define MYRIAD_UTIL #ifndef NULL #define NULL 0 #endif /* NULL */ #endif /* MUTIL_H */ bncsutil-1.4.5/src/bncsutil/mutil_types.h000066400000000000000000000021321523672167100205150ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Integer Types * November 12, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef BNCSUTIL_MUTIL_TYPES_H_INCLUDED #define BNCSUTIL_MUTIL_TYPES_H_INCLUDED #ifdef __cplusplus #include #else #include #endif #endif /* BNCSUTIL_MUTIL_TYPES_H_INCLUDED */ bncsutil-1.4.5/src/bncsutil/nls.c000066400000000000000000000423071523672167100167360ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * New Logon System (SRP) Implementation * February 13, 2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #if (defined(USE_MPIR) && USE_MPIR) #include "mpir.h" #else #include "gmp.h" #endif struct _nls { const char* username; const char* password; unsigned long username_len; unsigned long password_len; mpz_t n; mpz_t a; gmp_randstate_t rand; char* A; char* S; char* K; char* M1; char* M2; }; #ifdef MOS_WINDOWS # include # if DEBUG # define nls_dbg(msg) bncsutil_debug_message(msg) # else # define nls_dbg(msg) # endif #else # define nls_dbg(msg) # include #endif /* Raw large integer constants. */ const char bncsutil_NLS_I[] = { 0x6c, 0xe, 0x97, 0xed, 0xa, 0xf9, 0x6b, 0xab, 0xb1, 0x58, 0x89, 0xeb, 0x8b, 0xba, 0x25, 0xa4, 0xf0, 0x8c, 0x1, 0xf8 }; const char bncsutil_NLS_sig_n[] = { 0xD5, 0xA3, 0xD6, 0xAB, 0x0F, 0x0D, 0xC5, 0x0F, 0xC3, 0xFA, 0x6E, 0x78, 0x9D, 0x0B, 0xE3, 0x32, 0xB0, 0xFA, 0x20, 0xE8, 0x42, 0x19, 0xB4, 0xA1, 0x3A, 0x3B, 0xCD, 0x0E, 0x8F, 0xB5, 0x56, 0xB5, 0xDC, 0xE5, 0xC1, 0xFC, 0x2D, 0xBA, 0x56, 0x35, 0x29, 0x0F, 0x48, 0x0B, 0x15, 0x5A, 0x39, 0xFC, 0x88, 0x07, 0x43, 0x9E, 0xCB, 0xF3, 0xB8, 0x73, 0xC9, 0xE1, 0x77, 0xD5, 0xA1, 0x06, 0xA6, 0x20, 0xD0, 0x82, 0xC5, 0x2D, 0x4D, 0xD3, 0x25, 0xF4, 0xFD, 0x26, 0xFC, 0xE4, 0xC2, 0x00, 0xDD, 0x98, 0x2A, 0xF4, 0x3D, 0x5E, 0x08, 0x8A, 0xD3, 0x20, 0x41, 0x84, 0x32, 0x69, 0x8E, 0x8A, 0x34, 0x76, 0xEA, 0x16, 0x8E, 0x66, 0x40, 0xD9, 0x32, 0xB0, 0x2D, 0xF5, 0xBD, 0xE7, 0x57, 0x51, 0x78, 0x96, 0xC2, 0xED, 0x40, 0x41, 0xCC, 0x54, 0x9D, 0xFD, 0xB6, 0x8D, 0xC2, 0xBA, 0x7F, 0x69, 0x8D, 0xCF }; /* Private-use function prototypes. */ unsigned long nls_pre_seed(); void nls_get_x(const nls_t* nls, mpz_t x_c, const char* raw_salt); void nls_get_v_mpz(nls_t* nls, mpz_t v, mpz_t x); uint32_t nls_get_u(const char* B); /* Function definitons */ MEXP(nls_t*) nls_init(const char* username, const char* password) { return nls_init_l(username, (unsigned long) strlen(username), password, (unsigned long) strlen(password)); } MEXP(nls_t*) nls_init_l(const char* username, unsigned long username_length, const char* password, unsigned long password_length) { unsigned int i; char* d; /* destination */ const char* o; /* original */ nls_t* nls; nls = (nls_t*) malloc(sizeof(nls_t)); if (!nls) return (nls_t*) 0; nls->username_len = username_length; nls->password_len = password_length; nls->username = (char*) malloc(nls->username_len + 1); nls->password = (char*) malloc(nls->password_len + 1); if (!nls->username || !nls->password) { free(nls); return (nls_t*) 0; } d = (char*) nls->username; o = username; for (i = 0; i < nls->username_len; i++) { *d = (char) toupper(*o); d++; o++; } *((char*) nls->username + username_length) = 0; *((char*) nls->password + password_length) = 0; d = (char*) nls->password; o = password; for (i = 0; i < nls->password_len; i++) { *d = (char) toupper(*o); d++; o++; } mpz_init_set_str(nls->n, NLS_VAR_N_STR, 16); gmp_randinit_default(nls->rand); gmp_randseed_ui(nls->rand, nls_pre_seed()); mpz_init2(nls->a, 256); mpz_urandomm(nls->a, nls->rand, nls->n); /* generates the private key */ /* The following line replaces preceding 2 lines during testing. */ /*mpz_init_set_str(nls->a, "1234", 10);*/ nls->A = (char*) 0; nls->S = (char*) 0; nls->K = (char*) 0; nls->M1 = (char*) 0; nls->M2 = (char*) 0; return nls; } MEXP(void) nls_free(nls_t* nls) { mpz_clear(nls->a); mpz_clear(nls->n); gmp_randclear(nls->rand); free((void*) nls->username); free((void*) nls->password); if (nls->A) free(nls->A); if (nls->S) free(nls->S); if (nls->K) free(nls->K); if (nls->M1) free(nls->M1); if (nls->M2) free(nls->M2); free(nls); } MEXP(nls_t*) nls_reinit(nls_t* nls, const char* username, const char* password) { return nls_reinit_l(nls, username, (unsigned long) strlen(username), password, (unsigned long) strlen(password)); } MEXP(nls_t*) nls_reinit_l(nls_t* nls, const char* username, unsigned long username_length, const char* password, unsigned long password_length) { unsigned int i; char* d; /* destination */ const char* o; /* original */ if (nls->A) free(nls->A); if (nls->S) free(nls->S); if (nls->K) free(nls->K); if (nls->M1) free(nls->M1); if (nls->M2) free(nls->M2); nls->username_len = username_length; nls->password_len = password_length; nls->username = (const char*) realloc((void*) nls->username, nls->username_len + 1); if (!nls->username) { free(nls); return (nls_t*) 0; } nls->password = (const char*) realloc((void*) nls->password, nls->password_len + 1); if (!nls->password) { free((void*) nls->username); free(nls); return (nls_t*) 0; } d = (char*) nls->username; o = username; for (i = 0; i < nls->username_len; i++) { *d = (char) toupper(*o); d++; o++; } d = (char*) nls->password; o = password; for (i = 0; i < nls->password_len; i++) { *d = (char) toupper(*o); d++; o++; } *((char*) nls->username + username_length) = 0; *((char*) nls->password + password_length) = 0; mpz_urandomm(nls->a, nls->rand, nls->n); /* generates the private key */ nls->A = (char*) 0; nls->S = (char*) 0; nls->K = (char*) 0; nls->M1 = (char*) 0; nls->M2 = (char*) 0; return nls; } MEXP(unsigned long) nls_account_create(nls_t* nls, char* buf, unsigned long bufSize) { mpz_t s; /* salt */ mpz_t v; mpz_t x; if (!nls) return 0; if (bufSize < nls->username_len + 65) return 0; mpz_init2(s, 256); mpz_urandomb(s, nls->rand, 256); mpz_export(buf, (size_t*) 0, -1, 1, 0, 0, s); /*memset(buf, 0, 32);*/ nls_get_x(nls, x, buf); nls_get_v_mpz(nls, v, x); mpz_export(buf + 32, (size_t*) 0, -1, 1, 0, 0, v); mpz_clear(x); mpz_clear(v); mpz_clear(s); strcpy(buf + 64, nls->username); return nls->username_len + 65; } MEXP(unsigned long) nls_account_logon(nls_t* nls, char* buf, unsigned long bufSize) { if (!nls) return 0; if (bufSize < nls->username_len + 33) return 0; nls_get_A(nls, buf); strcpy(buf + 32, nls->username); return nls->username_len + 33; } MEXP(nls_t*) nls_account_change_proof(nls_t* nls, char* buf, const char* new_password, const char* B, const char* salt) { nls_t* nouveau; mpz_t s; /* salt */ if (!nls) return (nls_t*) 0; /* create new nls_t */ nouveau = nls_init_l(nls->username, nls->username_len, new_password, (unsigned long) strlen(new_password)); if (!nouveau) return (nls_t*) 0; /* fill buf */ nls_get_M1(nls, buf, B, salt); mpz_init2(s, 256); mpz_urandomb(s, nouveau->rand, 256); mpz_export(buf + 20, (size_t*) 0, -1, 1, 0, 0, s); nls_get_v(nouveau, buf + 52, buf + 20); mpz_clear(s); return nouveau; } MEXP(void) nls_get_S(nls_t* nls, char* out, const char* B, const char* salt) { mpz_t temp; mpz_t S_base, S_exp; mpz_t x; mpz_t v; if (!nls) return; if (nls->S) { memcpy(out, nls->S, 32); return; } mpz_init2(temp, 256); mpz_import(temp, 32, -1, 1, 0, 0, B); nls_get_x(nls, x, salt); nls_get_v_mpz(nls, v, x); mpz_init_set(S_base, nls->n); mpz_add(S_base, S_base, temp); mpz_sub(S_base, S_base, v); mpz_mod(S_base, S_base, nls->n); mpz_init_set(S_exp, x); mpz_mul_ui(S_exp, S_exp, nls_get_u(B)); mpz_add(S_exp, S_exp, nls->a); mpz_clear(x); mpz_clear(v); mpz_clear(temp); mpz_init(temp); mpz_powm(temp, S_base, S_exp, nls->n); mpz_clear(S_base); mpz_clear(S_exp); mpz_export(out, (size_t*) 0, -1, 1, 0, 0, temp); mpz_clear(temp); nls->S = (char*) malloc(32); if (nls->S) memcpy(nls->S, out, 32); } MEXP(void) nls_get_v(nls_t* nls, char* out, const char* salt) { mpz_t g; mpz_t v; mpz_t x; if (!nls) return; mpz_init_set_ui(g, NLS_VAR_g); mpz_init(v); nls_get_x(nls, x, salt); mpz_powm(v, g, x, nls->n); mpz_export(out, (size_t*) 0, -1, 1, 0, 0, v); mpz_clear(v); mpz_clear(g); mpz_clear(x); } MEXP(void) nls_get_A(nls_t* nls, char* out) { mpz_t g; mpz_t A; size_t o; if (!nls) return; if (nls->A) { memcpy(out, nls->A, 32); return; } mpz_init_set_ui(g, NLS_VAR_g); mpz_init2(A, 256); mpz_powm(A, g, nls->a, nls->n); mpz_export(out, &o, -1, 1, 0, 0, A); mpz_clear(A); mpz_clear(g); nls->A = (char*) malloc(32); if (nls->A) memcpy(nls->A, out, 32); } MEXP(void) nls_get_K(nls_t* nls, char* out, const char* S) { char odd[16], even[16]; uint8_t odd_hash[20], even_hash[20]; char* Sp = (char*) S; char* op = odd; char* ep = even; unsigned int i; SHA1Context ctx; if (!nls) return; if (nls->K) { memcpy(out, nls->K, 40); return; } for (i = 0; i < 16; i++) { *(op++) = *(Sp++); *(ep++) = *(Sp++); } SHA1Reset(&ctx); SHA1Input(&ctx, (uint8_t*) odd, 16); SHA1Result(&ctx, odd_hash); SHA1Reset(&ctx); SHA1Input(&ctx, (uint8_t*) even, 16); SHA1Result(&ctx, even_hash); Sp = out; op = (char*) odd_hash; ep = (char*) even_hash; for (i = 0; i < 20; i++) { *(Sp++) = *(op++); *(Sp++) = *(ep++); } nls->K = (char*) malloc(40); if (nls->K) memcpy(nls->K, out, 40); } MEXP(void) nls_get_M1(nls_t* nls, char* out, const char* B, const char* salt) { SHA1Context sha; uint8_t username_hash[20]; char A[32]; char S[32]; char K[40]; if (!nls) return; if (nls->M1) { nls_dbg("nls_get_M1(): Using cached M[1] value."); memcpy(out, nls->M1, 20); return; } /* calculate SHA-1 hash of username */ SHA1Reset(&sha); SHA1Input(&sha, (uint8_t*) nls->username, nls->username_len); SHA1Result(&sha, username_hash); nls_get_A(nls, A); nls_get_S(nls, S, B, salt); nls_get_K(nls, K, S); /* calculate M[1] */ SHA1Reset(&sha); SHA1Input(&sha, (uint8_t*) bncsutil_NLS_I, 20); SHA1Input(&sha, username_hash, 20); SHA1Input(&sha, (uint8_t*) salt, 32); SHA1Input(&sha, (uint8_t*) A, 32); SHA1Input(&sha, (uint8_t*) B, 32); SHA1Input(&sha, (uint8_t*) K, 40); SHA1Result(&sha, (uint8_t*) out); nls->M1 = (char*) malloc(20); if (nls->M1) memcpy(nls->M1, out, 20); } MEXP(int) nls_check_M2(nls_t* nls, const char* var_M2, const char* B, const char* salt) { SHA1Context sha; char local_M2[20]; char* A; char S[32]; char* K; char* M1; uint8_t username_hash[20]; int res; int mustFree = 0; if (!nls) return 0; if (nls->M2) return (memcmp(nls->M2, var_M2, 20) == 0); if (nls->A && nls->K && nls->M1) { A = nls->A; K = nls->K; M1 = nls->M1; } else { if (!B || !salt) return 0; A = (char*) malloc(32); if (!A) return 0; K = (char*) malloc(40); if (!K) { free(A); return 0; } M1 = (char*) malloc(20); if (!M1) { free(K); free(A); return 0; } mustFree = 1; /* get the other values needed for the hash */ nls_get_A(nls, A); nls_get_S(nls, S, (char*) B, (char*) salt); nls_get_K(nls, K, S); /* calculate SHA-1 hash of username */ SHA1Reset(&sha); SHA1Input(&sha, (uint8_t*) nls->username, nls->username_len); SHA1Result(&sha, username_hash); /* calculate M[1] */ SHA1Reset(&sha); SHA1Input(&sha, (uint8_t*) bncsutil_NLS_I, 20); SHA1Input(&sha, username_hash, 20); SHA1Input(&sha, (uint8_t*) salt, 32); SHA1Input(&sha, (uint8_t*) A, 32); SHA1Input(&sha, (uint8_t*) B, 32); SHA1Input(&sha, (uint8_t*) K, 40); SHA1Result(&sha, (uint8_t*) M1); } /* calculate M[2] */ SHA1Reset(&sha); SHA1Input(&sha, (uint8_t*) A, 32); SHA1Input(&sha, (uint8_t*) M1, 20); SHA1Input(&sha, (uint8_t*) K, 40); SHA1Result(&sha, (uint8_t*) local_M2); res = (memcmp(local_M2, var_M2, 20) == 0); if (mustFree) { free(A); free(K); free(M1); } /* cache result */ nls->M2 = (char*) malloc(20); if (nls->M2) memcpy(nls->M2, local_M2, 20); return res; } MEXP(int) nls_check_signature(uint32_t address, const char* signature_raw) { char* result_raw; char check[32]; mpz_t result; mpz_t modulus; mpz_t signature; size_t size, alloc_size; int cmp_result; /* build the "check" array */ memcpy(check, &address, 4); memset(check + 4, 0xBB, 28); /* initialize the modulus */ mpz_init2(modulus, 1024); mpz_import(modulus, 128, -1, 1, 0, 0, bncsutil_NLS_sig_n); /* initialize the server signature */ mpz_init2(signature, 1024); mpz_import(signature, 128, -1, 1, 0, 0, signature_raw); /* initialize the result */ mpz_init2(result, 1024); /* calculate the result */ mpz_powm_ui(result, signature, NLS_SIGNATURE_KEY, modulus); /* clear (free) the intermediates */ mpz_clear(signature); mpz_clear(modulus); /* allocate space for raw signature */ alloc_size = mpz_size(result) * sizeof(mp_limb_t); result_raw = (char*) malloc(alloc_size); if (!result_raw) { mpz_clear(result); return 0; } /* get a byte array of the signature */ mpz_export(result_raw, &size, -1, 1, 0, 0, result); /* clear (free) the result */ mpz_clear(result); /* check the result */ cmp_result = (memcmp(result_raw, check, 32) == 0); /* free the result_raw buffer */ free(result_raw); /* return */ return cmp_result; } unsigned long nls_pre_seed() { #ifdef MOS_WINDOWS return (unsigned long) GetTickCount(); #else FILE* f; unsigned long r; /* try to get data from /dev/random or /dev/urandom */ f = fopen("/dev/urandom", "r"); if (!f) { f = fopen("/dev/random", "r"); if (!f) { srand(time(NULL)); return (unsigned long) rand(); } } if (fread(&r, sizeof(unsigned long), 1, f) != 1) { fclose(f); srand(time(NULL)); return (unsigned long) rand(); } fclose(f); return r; #endif } void nls_get_x(const nls_t* nls, mpz_t x_c, const char* raw_salt) { char* userpass; uint8_t hash[20], final_hash[20]; SHA1Context shac; // build the string Username:Password userpass = (char*) malloc(nls->username_len + nls->password_len + 2); memcpy(userpass, nls->username, nls->username_len); userpass[nls->username_len] = ':'; memcpy(userpass + nls->username_len + 1, nls->password, nls->password_len); userpass[nls->username_len + nls->password_len + 1] = 0; // null-terminator // get the SHA-1 hash of the string SHA1Reset(&shac); SHA1Input(&shac, (uint8_t*) userpass, (nls->username_len + nls->password_len + 1)); SHA1Result(&shac, hash); free(userpass); // get the SHA-1 hash of the salt and user:pass hash SHA1Reset(&shac); SHA1Input(&shac, (uint8_t*) raw_salt, 32); SHA1Input(&shac, hash, 20); SHA1Result(&shac, final_hash); SHA1Reset(&shac); // create an arbitrary-length integer from the hash and return it mpz_init2(x_c, 160); mpz_import(x_c, 20, -1, 1, 0, 0, (char*) final_hash); } void nls_get_v_mpz(nls_t* nls, mpz_t v, mpz_t x) { mpz_t g; mpz_init_set_ui(g, NLS_VAR_g); mpz_init(v); mpz_powm(v, g, x, nls->n); mpz_clear(g); } uint32_t nls_get_u(const char* B) { SHA1Context sha; uint8_t hash[20]; uint32_t u; SHA1Reset(&sha); SHA1Input(&sha, (uint8_t*) B, 32); SHA1Result(&sha, hash); SHA1Reset(&sha); u = *(uint32_t*) hash; u = MSB4(u); // needed? yes return u; } bncsutil-1.4.5/src/bncsutil/nls.h000066400000000000000000000226411523672167100167420ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * New Logon System (SRP) Interface * November 26, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef BNCSUTIL_NLS_H_INCLUDED #define BNCSUTIL_NLS_H_INCLUDED #include // modulus ("N") in base-16 #define NLS_VAR_N_STR \ "F8FF1A8B619918032186B68CA092B5557E976C78C73212D91216F6658523C787" // generator var ("g") #define NLS_VAR_g 0x2F // SHA1(g) ^ SHA1(N) ("I") #define NLS_VAR_I_STR "8018CF0A425BA8BEB8958B1AB6BF90AED970E6C" // Server Signature Key #define NLS_SIGNATURE_KEY 0x10001 #ifdef __cplusplus extern "C" { #endif /** * Data type used by NLS functions. */ typedef struct _nls nls_t; /** * Allocates and initializes an nls_t structure. * Returns a NULL pointer on failure. */ MEXP(nls_t*) nls_init(const char* username, const char* password); /** * Allocates and initializes an nls_t structure, using the given string lengths. * Returns a NULL pointer on failure. * (Lengths do not include the null-terminator.) */ MEXP(nls_t*) nls_init_l(const char* username, unsigned long username_length, const char* password, unsigned long password_length); /** * Frees an nls_t structure. */ MEXP(void) nls_free(nls_t* nls); /** * Re-initializes an nls_t structure with a new username and * password. Returns the nls argument on success or a NULL * pointer on failure. */ MEXP(nls_t*) nls_reinit(nls_t* nls, const char* username, const char* password); /** * Re-initializes an nls_t structure with a new username and * password and their given lengths. Returns the nls argument * on success or a NULL pointer on failure. */ MEXP(nls_t*) nls_reinit_l(nls_t* nls, const char* username, unsigned long username_length, const char* password, unsigned long password_length); /* Packet Generation Functions */ /** * Builds the content of an SID_AUTH_ACCOUNTCREATE packet. * buf should be at least strlen(username) + 65 bytes long. * bufSize should be the size of buf. * Returns the number of bytes placed in buf, or 0 on error. */ MEXP(unsigned long) nls_account_create(nls_t* nls, char* buf, unsigned long bufSize); /** * [ DEPRECATED ] Uses the internal username buffer when * generating the packet, which is in all * upper-case. * * Builds the content of an SID_AUTH_ACCOUNTLOGON packet. * buf should be at least strlen(username) + 33 bytes long. * bufSize should be size of buf. * Returns the number of bytes placed in buf, or 0 on error. */ MEXP(unsigned long) nls_account_logon(nls_t* nls, char* buf, unsigned long bufSize); /** * NOTE * There is no nls_account_logon_proof function, as it'd be the same as * nls_get_M1, and no nls_account_change function, as it's probably easier to * just assemble that packet yourself. */ /** * Builds the content of an SID_AUTH_ACCOUNTCHANGEPROOF packet and places it in * buf, which should be at least 84 bytes long. The account's new password * should be placed in new_password. A new nls_t* pointer will be returned * as if you'd called nls_init. If you're not going to check the server * password proof (the response to this packet) then you can nls_free the value * of nls and use the returned value. Any login operations with the new * password should use the returned value. Returns a NULL pointer on error. */ MEXP(nls_t*) nls_account_change_proof(nls_t* nls, char* buf, const char* new_password, const char* B, const char* salt); /* Calculation Functions */ /** * Gets the "secret" value (S). (32 bytes) */ MEXP(void) nls_get_S(nls_t* nls, char* out, const char* B, const char* salt); /** * Gets the password verifier (v). (32 bytes) */ MEXP(void) nls_get_v(nls_t* nls, char* out, const char* salt); /** * Gets the public key (A). (32 bytes) */ MEXP(void) nls_get_A(nls_t* nls, char* out); /** * Gets "K" value, which is based on the secret (S). * The buffer "out" must be at least 40 bytes long. */ MEXP(void) nls_get_K(nls_t* nls, char* out, const char* S); /** * Gets the "M[1]" value, which proves that you know your password. * The buffer "out" must be at least 20 bytes long. */ MEXP(void) nls_get_M1(nls_t* nls, char* out, const char* B, const char* salt); /** * Checks the "M[2]" value, which proves that the server knows your * password. Pass the M2 value in the var_M2 argument. Returns 0 * if the check failed, nonzero if the proof matches. Now that * calculated value caching has been added, B and salt can be * safely set to NULL. */ MEXP(int) nls_check_M2(nls_t* nls, const char* var_M2, const char* B, const char* salt); /** * Checks the server signature received in SID_AUTH_INFO (0x50). * Pass the IPv4 address of the server you're connecting to in the address * paramater and the 128-byte server signature in the signature_raw paramater. * Address paramater should be in network byte order (big-endian). * Returns a nonzero value if the signature matches or 0 on failure. * Note that this function does NOT take an nls_t* argument! */ MEXP(int) nls_check_signature(uint32_t address, const char* signature_raw); #ifdef __cplusplus } // extern "C" #include #include #include /** * NLS convenience class. Getter functions which return pointers return those * pointers from dynamically-allocated memory that will be automatically freed * when the NLS object is destroyed. They should not be free()'d or deleted. */ class NLS { public: NLS(const char* username, const char* password) : n((nls_t*) 0) { n = nls_init(username, password); } NLS(const char* username, size_t username_length, const char* password, size_t password_length) { n = nls_init_l(username, username_length, password, password_length); } NLS(const std::string& username, const std::string& password) { n = nls_init_l(username.c_str(), username.length(), password.c_str(), password.length()); } virtual ~NLS() { std::vector::iterator i; if (n) nls_free(n); for (i = blocks.begin(); i != blocks.end(); i++) { delete [] *i; } } void getSecret(char* out, const char* salt, const char* B) { nls_get_S(n, out, B, salt); } const char* getSecret(const char* salt, const char* B) { char* buf = allocateBuffer(32); getSecret(buf, salt, B); return buf; } void getVerifier(char* out, const char* salt) { nls_get_v(n, out, salt); } const char* getVerifier(const char* salt) { char* buf = allocateBuffer(32); getVerifier(buf, salt); return buf; } void getPublicKey(char* out) { nls_get_A(n, out); } const char* getPublicKey(void) { char* buf = allocateBuffer(32); getPublicKey(buf); return buf; } void getHashedSecret(char* out, const char* secret) { nls_get_K(n, out, secret); } const char* getHashedSecret(const char* secret) { char* buf = allocateBuffer(40); getHashedSecret(buf, secret); return buf; } void getClientSessionKey(char* out, const char* salt, const char* B) { nls_get_M1(n, out, B, salt); } const char* getClientSessionKey(const char* salt, const char* B) { char* buf = allocateBuffer(20); getClientSessionKey(buf, salt, B); return buf; } bool checkServerSessionKey(const char* key, const char* salt, const char* B) { return (nls_check_M2(n, key, B, salt) != 0); } NLS makeChangeProof(char* buf, const char* new_password, const char* salt, const char* B) { return NLS(nls_account_change_proof(n, buf, new_password, B, salt)); } NLS makeChangeProof(char* buf, const std::string& new_password, const char* salt, const char* B) { return NLS(nls_account_change_proof(n, buf, new_password.c_str(), B, salt)); } std::pair makeChangeProof(const char* new_password, const char* salt, const char* B) { char* buf = allocateBuffer(84); NLS nls = NLS(nls_account_change_proof(n, buf, new_password, B, salt)); return std::pair(nls, buf); } std::pair makeChangeProof(const std::string& new_password, const char* salt, const char* B) { return makeChangeProof(new_password.c_str(), salt, B); } private: std::vector blocks; nls_t* n; NLS(nls_t* nls) { n = nls; } char* allocateBuffer(size_t length) { char* buf = new char[length]; blocks.push_back(buf); return buf; } }; #endif #endif /* BNCSUTIL_NLS_H_INCLUDED */ bncsutil-1.4.5/src/bncsutil/oldauth.cpp000066400000000000000000000041211523672167100201320ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Old Logon System Implementation * October 23, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #include // for MEXP() #include #include #include // for strlen /** * Double-hashes the given password using the given * server and client tokens. * * outBuffer MUST be at least 20 bytes long. */ MEXP(void) doubleHashPassword(const char* password, uint32_t clientToken, uint32_t serverToken, char* outBuffer) { char intermediate[28]; uint32_t* lp; calcHashBuf(password, std::strlen(password), intermediate + 8); lp = (uint32_t*) &intermediate; lp[0] = clientToken; lp[1] = serverToken; calcHashBuf(intermediate, 28, outBuffer); #if DEBUG bncsutil_debug_message_a("doubleHashPassword(\"%s\", 0x%08X, 0x%08X) =", password, clientToken, serverToken); bncsutil_debug_dump(outBuffer, 20); #endif } /** * Single-hashes the password for account creation and password changes. * * outBuffer MUST be at least 20 bytes long. */ MEXP(void) hashPassword(const char* password, char* outBuffer) { calcHashBuf(password, std::strlen(password), outBuffer); #if DEBUG bncsutil_debug_message_a("hashPassword(\"%s\") =", password); bncsutil_debug_dump(outBuffer, 20); #endif } bncsutil-1.4.5/src/bncsutil/oldauth.h000066400000000000000000000026421523672167100176050ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Old Logon System * October 23, 2004 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef BNCSUTIL_OLDAUTH_H #define BNCSUTIL_OLDAUTH_H #ifdef __cplusplus extern "C" { #endif /** * Double-hashes the given password using the given * server and client tokens. */ MEXP(void) doubleHashPassword(const char* password, uint32_t clientToken, uint32_t serverToken, char* outBuffer); /** * Single-hashes the password for account creation and password changes. */ MEXP(void) hashPassword(const char* password, char* outBuffer); #ifdef __cplusplus } // extern "C" #endif #endif /* BNCSUTIL_OLDAUTH_H */ bncsutil-1.4.5/src/bncsutil/pe.c000066400000000000000000000371541523672167100165520ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Portable Executable Processing * August 16, 2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #include #include #include #include int cm_pe_load_resdir(FILE* f, uint32_t offset, cm_pe_resdir_t* dir); MEXP(cm_pe_t) cm_pe_load(const char* filename) { cm_pe_t pe; cm_pe_header_t* header; cm_pe_optional_header_t* opt_header; cm_pe_windows_header_t* win_header; long pe_offset = 0; //size_t i; size_t count; pe = (cm_pe_t) malloc(sizeof(struct cm_pe)); if (!pe) return (cm_pe_t) 0; memset(pe, 0, sizeof(struct cm_pe)); pe->f = fopen(filename, "r"); if (!pe->f) { free(pe); return (cm_pe_t) 0; } if (fseek(pe->f, 0x3CL, SEEK_SET) == -1) goto err_trap; if (fread(&pe_offset, 4, 1, pe->f) != 1) goto err_trap; #if BIG_ENDIAN pe_offset = LSB4(pe_offset); #endif if (fseek(pe->f, pe_offset, SEEK_SET) == -1) goto err_trap; if (fread(&pe->header, sizeof(cm_pe_header_t), 1, pe->f) != 1) goto err_trap; header = &pe->header; #if BIGENDIAN /* Without regular expressions, this would've sucked. */ header->signature = SWAP32(header->signature); header->machine = SWAP16(header->machine); header->section_count = SWAP16(header->section_count); header->timestamp = SWAP32(header->timestamp); header->symbol_table_offset = SWAP32(header->symbol_table_offset); header->symbol_count = SWAP32(header->symbol_count); header->optional_header_size = SWAP16(header->optional_header_size); header->characteristics = SWAP16(header->characteristics); #endif if (header->optional_header_size > 0) { if (fread(&pe->optional_header, PE_OPTIONAL_HEADER_MIN_SIZE, 1, pe->f) != 1) { goto err_trap; } opt_header = &pe->optional_header; win_header = &pe->windows_header; #if BIGENDIAN opt_header->magic = SWAP16(opt_header->magic); #endif if (opt_header->magic == IMAGE_FORMAT_PE32) { if (fread(&opt_header->data_base, 4, 1, pe->f) != 1) goto err_trap; if (fread(&win_header->image_base, 4, 1, pe->f) != 1) goto err_trap; // The 40 is not a typo. if (fread(&win_header->section_alignment, 40, 1, pe->f) != 1) goto err_trap; if (fread(&win_header->stack_reserve_size, 4, 1, pe->f) != 1) goto err_trap; if (fread(&win_header->stack_commit_size, 4, 1, pe->f) != 1) goto err_trap; if (fread(&win_header->heap_reserve_size, 4, 1, pe->f) != 1) goto err_trap; if (fread(&win_header->heap_commit_size, 4, 1, pe->f) != 1) goto err_trap; if (fread(&win_header->loader_flags, 4, 1, pe->f) != 1) goto err_trap; if (fread(&win_header->data_directory_count, 4, 1, pe->f) != 1) goto err_trap; } else if (opt_header->magic == IMAGE_FORMAT_PE32_PLUS) { if (fread(win_header, sizeof(cm_pe_windows_header_t), 1, pe->f)!= 1) goto err_trap; } else { goto err_trap; } #if BIGENDIAN opt_header->code_section_size = SWAP32(opt_header->code_section_size); opt_header->initialized_data_size = SWAP32(opt_header->initialized_data_size); opt_header->uninitialized_data_size = SWAP32(opt_header->uninitialized_data_size); opt_header->entry_point = SWAP32(opt_header->entry_point); opt_header->code_base = SWAP32(opt_header->code_base); opt_header->data_base = SWAP32(opt_header->data_base); win_header->image_base = SWAP64(win_header->image_base); win_header->section_alignment = SWAP32(win_header->section_alignment); win_header->file_alignment = SWAP32(win_header->file_alignment); win_header->major_os_version = SWAP16(win_header->major_os_version); win_header->minor_os_version = SWAP16(win_header->minor_os_version); win_header->major_image_version = SWAP16(win_header->major_image_version); win_header->minor_image_version = SWAP16(win_header->minor_image_version); win_header->major_subsystem_version = SWAP16(win_header->major_subsystem_version); win_header->minor_subsystem_version = SWAP16(win_header->minor_subsystem_version); win_header->reserved = SWAP32(win_header->reserved); win_header->image_size = SWAP32(win_header->image_size); win_header->headers_size = SWAP32(win_header->headers_size); win_header->checksum = SWAP32(win_header->checksum); win_header->subsystem = SWAP16(win_header->subsystem); win_header->dll_characteristics = SWAP16(win_header->dll_characteristics); win_header->stack_reserve_size = SWAP64(win_header->stack_reserve_size); win_header->stack_commit_size = SWAP64(win_header->stack_commit_size); win_header->heap_reserve_size = SWAP64(win_header->heap_reserve_size); win_header->heap_commit_size = SWAP64(win_header->heap_commit_size); win_header->loader_flags = SWAP32(win_header->loader_flags); win_header->data_directory_count = SWAP32(win_header->data_directory_count); #endif if (win_header->data_directory_count > 0) { count = win_header->data_directory_count; pe->data_directories = (cm_pe_data_directory_t*) calloc(sizeof(cm_pe_data_directory_t), count); if (!pe->data_directories) goto err_trap; if (fread(pe->data_directories, sizeof(cm_pe_data_directory_t), count, pe->f) != count) { goto dir_err_trap; } #if BIGENDIAN for (i = 0; i < count; i++) { pe->data_directories[i].rva = SWAP32(pe->data_directories[i].rva); pe->data_directories[i].size = SWAP32(pe->data_directories[i].size); } #endif } count = (size_t) header->section_count; if (count) { pe->sections = (cm_pe_section_t*) calloc(sizeof(cm_pe_section_t), count); if (!pe->sections) goto dir_err_trap; if (fread(pe->sections, sizeof(cm_pe_section_t), count, pe->f) != count) { goto sect_err_trap; } } #if BIGENDIAN for (i = 0; i < count; i++) { pe->sections[i].virtual_size = SWAP32(pe->sections[i].virtual_size); pe->sections[i].virtual_address = SWAP32(pe->sections[i].virtual_address); pe->sections[i].raw_data_size = SWAP32(pe->sections[i].raw_data_size); pe->sections[i].raw_data_offset = SWAP32(pe->sections[i].raw_data_offset); pe->sections[i].relocations_offset = SWAP32(pe->sections[i].relocations_offset); pe->sections[i].line_numbers_offset = SWAP32(pe->sections[i].line_numbers_offset); pe->sections[i].relocation_count = SWAP16(pe->sections[i].relocation_count); pe->sections[i].line_number_count = SWAP16(pe->sections[i].line_number_count); pe->sections[i].characteristics = SWAP32(pe->sections[i].characteristics); } #endif } return pe; sect_err_trap: free(pe->sections); dir_err_trap: free(pe->data_directories); err_trap: fclose(pe->f); free(pe); return (cm_pe_t) 0; } MEXP(void) cm_pe_unload(cm_pe_t pe) { if (pe->data_directories) free(pe->data_directories); if (pe->sections) free(pe->sections); if (pe->f) fclose(pe->f); free(pe); } static cm_pe_section_t* cm_pe_get_section(cm_pe_t pe, const char* name) { unsigned int i; cm_pe_section_t* s; uint32_t section_count = pe->header.section_count; if (!pe || !pe->sections) return (cm_pe_section_t*) 0; for (i = 0, s = pe->sections; i < section_count; i++, s++) { if (strcmp(s->name, name) == 0) return s; } return (cm_pe_section_t*) 0; } MEXP(cm_pe_resdir_t*) cm_pe_load_resources(cm_pe_t pe) { cm_pe_section_t* sect; cm_pe_resdir_t* root = (cm_pe_resdir_t*) 0; cm_pe_resdir_t* dir; cm_pe_resdir_t* subdirs; cm_pe_res_t res; cm_pe_res_t* resources; cm_stack_t stack; size_t i; uint32_t base; // no need to check validity of pe pointer; cm_pe_get_section does this sect = cm_pe_get_section(pe, ".rsrc"); if (!sect) return (cm_pe_resdir_t*) 0; root = (cm_pe_resdir_t*) malloc(sizeof(cm_pe_resdir_t)); if (!root) return (cm_pe_resdir_t*) 0; base = sect->raw_data_offset; if (!cm_pe_load_resdir(pe->f, base, root)) { free(root); return (cm_pe_resdir_t*) 0; } stack = cm_stack_create(); if (!stack) { free(root); return (cm_pe_resdir_t*) 0; } cm_stack_push(stack, root); while ( (dir = (cm_pe_resdir_t*) cm_stack_pop(stack)) ) { while (dir->subdir_count + dir->resource_count < dir->named_entry_count + dir->id_entry_count) { if (fseek(pe->f, dir->offset, SEEK_SET) == -1) { cm_pe_unload_resources(root); cm_stack_destroy(stack); return (cm_pe_resdir_t*) 0; } if (fread(&res, CM_RES_REAL_SIZE, 1, pe->f) != 1) { cm_pe_unload_resources(root); cm_stack_destroy(stack); return (cm_pe_resdir_t*) 0; } #if BIGENDIAN res.name = SWAP4(res.name); res.offset = SWAP4(res.offset); #endif if (res.offset & 0x80000000) { // subdirectory i = dir->subdir_count++; subdirs = (cm_pe_resdir_t*) realloc(dir->subdirs, sizeof(cm_pe_resdir_t) * dir->subdir_count); if (!subdirs) { cm_pe_unload_resources(root); cm_stack_destroy(stack); return (cm_pe_resdir_t*) 0; } dir->subdirs = subdirs; cm_stack_push(stack, dir); dir->offset += CM_RES_REAL_SIZE; dir = (subdirs + i); res.offset &= 0x7FFFFFFF; res.file_offset = base + res.offset; if (!cm_pe_load_resdir(pe->f, res.file_offset, dir)) { cm_pe_unload_resources(root); cm_stack_destroy(stack); return (cm_pe_resdir_t*) 0; } dir->name = res.name; cm_stack_push(stack, dir); break; } // real resource res.file_offset = base + res.offset; i = dir->resource_count++; resources = (cm_pe_res_t*) realloc(dir->resources, sizeof(cm_pe_res_t) * dir->resource_count); if (!resources) { cm_pe_unload_resources(root); cm_stack_destroy(stack); return (cm_pe_resdir_t*) 0; } dir->resources = resources; memcpy(dir->resources + i, &res, sizeof(cm_pe_res_t)); dir->offset += CM_RES_REAL_SIZE; } } cm_stack_destroy(stack); return root; } MEXP(int) cm_pe_unload_resources(cm_pe_resdir_t* root) { cm_pe_resdir_t* dir; cm_stack_t stack; stack = cm_stack_create(); if (!stack) return 0; cm_stack_push(stack, root); while ( (dir = cm_stack_pop(stack)) ) { if (dir->subdir_count) { dir->subdir_count--; cm_stack_push(stack, dir); cm_stack_push(stack, (dir->subdirs + dir->subdir_count)); continue; } if (dir->subdirs) { free(dir->subdirs); dir->subdirs = (cm_pe_resdir_t*) 0; } if (dir->resources) { free(dir->resources); dir->resource_count = 0; } } cm_stack_destroy(stack); free(root); return 1; } MEXP(int) cm_pe_fixed_version(cm_pe_t pe, cm_pe_res_t* res, cm_pe_version_t* ver) { // find ".rsrc" section cm_pe_section_t* sect = pe->sections; { int i=0; for(; iheader.section_count; ++i) { if(strncmp(sect[i].name,".rsrc",sizeof(sect[i].name))==0) { sect = §[i]; break; } } if(i == pe->header.section_count) // no resources ??? return 0; } #if BIGENDIAN uint32_t check = 0xBD04EFFE; #else uint32_t check = 0xFEEF04BD; #endif uint32_t rva; uint32_t size; uint32_t offset; if (!pe || !res || !ver) return 0; if (fseek(pe->f, res->file_offset, SEEK_SET) == -1) return 0; if (fread(&rva, 4, 1, pe->f) != 1) return 0; if (fread(&size, 4, 1, pe->f) != 1) return 0; #if BIGENDIAN rva = SWAP4(rva); size = SWAP4(size); #endif offset = sect->raw_data_offset + (rva - sect->virtual_address) + 0x26; offset = (offset+3) & 0xFFFFFFFC; // align 4 byte if (fseek(pe->f, offset, SEEK_SET) == -1) return 0; if (fread(ver, sizeof(cm_pe_version_t), 1, pe->f) != 1) return 0; if (ver->dwSignature != check) return 0; #if BIGENDIAN ver->dwSignature = SWAP32(ver->dwSignature); ver->dwStrucVersion = SWAP32(ver->dwStrucVersion); ver->dwFileVersionMS = SWAP32(ver->dwFileVersionMS); ver->dwFileVersionLS = SWAP32(ver->dwFileVersionLS); ver->dwProductVersionMS = SWAP32(ver->dwProductVersionMS); ver->dwProductVersionLS = SWAP32(ver->dwProductVersionLS); ver->dwFileFlagsMask = SWAP32(ver->dwFileFlagsMask); ver->dwFileFlags = SWAP32(ver->dwFileFlags); ver->dwFileOS = SWAP32(ver->dwFileOS); ver->dwFileType = SWAP32(ver->dwFileType); ver->dwFileSubtype = SWAP32(ver->dwFileSubtype); ver->dwFileDateMS = SWAP32(ver->dwFileDateMS); ver->dwFileDateLS = SWAP32(ver->dwFileDateLS); #endif return 1; } int cm_pe_load_resdir(FILE* f, uint32_t offset, cm_pe_resdir_t* dir) { memset(dir, 0, sizeof(cm_pe_resdir_t)); if (fseek(f, offset, SEEK_SET) == -1) return 0; if (fread(dir, 16, 1, f) != 1) return 0; #if BIGENDIAN dir->characteristics = SWAP32(dir->characteristics); dir->timestamp = SWAP32(dir->timestamp); dir->major_version = SWAP16(dir->major_version); dir->minor_version = SWAP16(dir->minor_version); dir->named_entry_count = SWAP16(dir->named_entry_count); dir->id_entry_count = SWAP16(dir->id_entry_count); #endif dir->offset = (uint32_t) ftell(f); return 1; } bncsutil-1.4.5/src/bncsutil/pe.h000066400000000000000000000130371523672167100165510ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Portable Executable Processing * August 16, 2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #ifndef CM_PE_H_INCLUDED #define CM_PE_H_INCLUDED 1 #include "mutil.h" #ifdef __cplusplus #include #else #include #endif #ifdef __cplusplus extern "C" { #endif typedef struct cm_pe_header { uint32_t signature; uint16_t machine; // IMAGE_FILE_MACHINE_* uint16_t section_count; uint32_t timestamp; uint32_t symbol_table_offset; uint32_t symbol_count; uint16_t optional_header_size; uint16_t characteristics; } cm_pe_header_t; #define IMAGE_FORMAT_PE32 0x10B #define IMAGE_FORMAT_PE32_PLUS 0x20B typedef struct cm_pe_optional_header { uint16_t magic; // image format (PE32/PE32+) uint8_t major_linker_version; uint8_t minor_linker_version; uint32_t code_section_size; uint32_t initialized_data_size; uint32_t uninitialized_data_size; uint32_t entry_point; uint32_t code_base; uint32_t data_base; // not present in PE32+! } cm_pe_optional_header_t; #define PE_OPTIONAL_HEADER_MIN_SIZE (sizeof(cm_pe_optional_header_t) - 4) typedef struct cm_pe_windows_header { uint64_t image_base; uint32_t section_alignment; uint32_t file_alignment; uint16_t major_os_version; uint16_t minor_os_version; uint16_t major_image_version; uint16_t minor_image_version; uint16_t major_subsystem_version; uint16_t minor_subsystem_version; uint32_t reserved; uint32_t image_size; uint32_t headers_size; uint32_t checksum; uint16_t subsystem; uint16_t dll_characteristics; uint64_t stack_reserve_size; uint64_t stack_commit_size; uint64_t heap_reserve_size; uint64_t heap_commit_size; uint32_t loader_flags; uint32_t data_directory_count; } cm_pe_windows_header_t; typedef struct cm_pe_data_directory { uint32_t rva; uint32_t size; } cm_pe_data_directory_t; typedef struct cm_pe_section { char name[8]; uint32_t virtual_size; uint32_t virtual_address; uint32_t raw_data_size; uint32_t raw_data_offset; uint32_t relocations_offset; uint32_t line_numbers_offset; uint16_t relocation_count; uint16_t line_number_count; uint32_t characteristics; } cm_pe_section_t; typedef struct VS_FIXEDFILEINFO { uint32_t dwSignature; uint32_t dwStrucVersion; uint32_t dwFileVersionMS; uint32_t dwFileVersionLS; union { struct { uint32_t dwProductVersionMS; uint32_t dwProductVersionLS; }; uint64_t qwProductVersion; }; uint32_t dwFileFlagsMask; uint32_t dwFileFlags; uint32_t dwFileOS; uint32_t dwFileType; uint32_t dwFileSubtype; union { struct { uint32_t dwFileDateMS; uint32_t dwFileDateLS; }; uint64_t qwFileDate; }; } cm_pe_version_t; typedef struct cm_pe_resource { uint32_t name; uint32_t offset; uint32_t file_offset; } cm_pe_res_t; #define CM_RES_REAL_SIZE 8 typedef struct cm_pe_resdir { uint32_t characteristics; uint32_t timestamp; uint16_t major_version; uint16_t minor_version; uint16_t named_entry_count; uint16_t id_entry_count; size_t subdir_count; struct cm_pe_resdir* subdirs; size_t resource_count; cm_pe_res_t* resources; uint32_t offset; uint32_t name; } cm_pe_resdir_t; typedef struct cm_pe { FILE* f; cm_pe_header_t header; cm_pe_optional_header_t optional_header; cm_pe_windows_header_t windows_header; cm_pe_data_directory_t* data_directories; cm_pe_section_t* sections; } *cm_pe_t; #define IMAGE_FILE_MACHINE_UNKNOWN 0x0 #define IMAGE_FILE_MACHINE_ALPHA 0x184 #define IMAGE_FILE_MACHINE_ARM 0x1c0 #define IMAGE_FILE_MACHINE_ALPHA64 0x284 #define IMAGE_FILE_MACHINE_I386 0x14c #define IMAGE_FILE_MACHINE_IA64 0x200 #define IMAGE_FILE_MACHINE_M68K 0x268 #define IMAGE_FILE_MACHINE_MIPS16 0x266 #define IMAGE_FILE_MACHINE_MIPSFPU 0x366 #define IMAGE_FILE_MACHINE_MIPSFPU16 0x466 #define IMAGE_FILE_MACHINE_POWERPC 0x1f0 #define IMAGE_FILE_MACHINE_R3000 0x162 #define IMAGE_FILE_MACHINE_R4000 0x166 #define IMAGE_FILE_MACHINE_R10000 0x168 #define IMAGE_FILE_MACHINE_SH3 0x1a2 #define IMAGE_FILE_MACHINE_SH4 0x1a6 #define IMAGE_FILE_MACHINE_THUMB 0x1c2 MEXP(cm_pe_t) cm_pe_load(const char* filename); MEXP(void) cm_pe_unload(cm_pe_t pe); MEXP(cm_pe_resdir_t*) cm_pe_load_resources(cm_pe_t pe); MEXP(int) cm_pe_unload_resources(cm_pe_resdir_t* dir); MEXP(int) cm_pe_fixed_version(cm_pe_t pe, cm_pe_res_t* res, cm_pe_version_t* ver); #ifdef __cplusplus } #endif #endif bncsutil-1.4.5/src/bncsutil/sha1.c000066400000000000000000000240731523672167100167760ustar00rootroot00000000000000/* * sha1.c * * Description: * This file implements the Secure Hashing Algorithm 1 as * defined in FIPS PUB 180-1 published April 17, 1995. * * The SHA-1, produces a 160-bit message digest for a given * data stream. It should take about 2**n steps to find a * message with the same digest as a given message and * 2**(n/2) to find any two messages with the same digest, * when n is the digest size in bits. Therefore, this * algorithm can serve as a means of providing a * "fingerprint" for a message. * * Portability Issues: * SHA-1 is defined in terms of 32-bit "words". This code * uses (included via "sha1.h" to define 32 and 8 * bit unsigned integer types. If your C compiler does not * support 32 bit unsigned integers, this code is not * appropriate. * * Caveats: * SHA-1 is designed to work with messages less than 2^64 bits * long. Although SHA-1 allows a message digest to be generated * for messages of any number of bits less than 2^64, this * implementation only works with messages with a length that is * a multiple of the size of an 8-bit character. * */ #include /* * Define the SHA1 circular left shift macro */ #define SHA1CircularShift(bits,word) \ (((word) << (bits)) | ((word) >> (32-(bits)))) /* Local Function Prototyptes */ void SHA1PadMessage(SHA1Context * /*context*/); void SHA1ProcessMessageBlock(SHA1Context * /*context*/); /* * SHA1Reset * * Description: * This function will initialize the SHA1Context in preparation * for computing a new SHA1 message digest. * * Parameters: * context: [in/out] * The context to reset. * * Returns: * sha Error Code. * */ int SHA1Reset(SHA1Context *context) { if (!context) { return shaNull; } context->Length_Low = 0; context->Length_High = 0; context->Message_Block_Index = 0; context->Intermediate_Hash[0] = 0x67452301; context->Intermediate_Hash[1] = 0xEFCDAB89; context->Intermediate_Hash[2] = 0x98BADCFE; context->Intermediate_Hash[3] = 0x10325476; context->Intermediate_Hash[4] = 0xC3D2E1F0; context->Computed = 0; context->Corrupted = 0; return shaSuccess; } /* * SHA1Result * * Description: * This function will return the 160-bit message digest into the * Message_Digest array provided by the caller. * NOTE: The first octet of hash is stored in the 0th element, * the last octet of hash in the 19th element. * * Parameters: * context: [in/out] * The context to use to calculate the SHA-1 hash. * Message_Digest: [out] * Where the digest is returned. * * Returns: * sha Error Code. * */ int SHA1Result( SHA1Context *context, uint8_t Message_Digest[SHA1HashSize]) { int i; if (!context || !Message_Digest) { return shaNull; } if (context->Corrupted) { return context->Corrupted; } if (!context->Computed) { SHA1PadMessage(context); for(i=0; i<64; ++i) { /* message may be sensitive, clear it out */ context->Message_Block[i] = 0; } context->Length_Low = 0; /* and clear length */ context->Length_High = 0; context->Computed = 1; } for(i = 0; i < SHA1HashSize; ++i) { Message_Digest[i] = context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ); } return shaSuccess; } /* * SHA1Input * * Description: * This function accepts an array of octets as the next portion * of the message. * * Parameters: * context: [in/out] * The SHA context to update * message_array: [in] * An array of characters representing the next portion of * the message. * length: [in] * The length of the message in message_array * * Returns: * sha Error Code. * */ int SHA1Input( SHA1Context *context, const uint8_t *message_array, unsigned length) { if (!length) { return shaSuccess; } if (!context || !message_array) { return shaNull; } if (context->Computed) { context->Corrupted = shaStateError; return shaStateError; } if (context->Corrupted) { return context->Corrupted; } while(length-- && !context->Corrupted) { context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF); context->Length_Low += 8; if (context->Length_Low == 0) { context->Length_High++; if (context->Length_High == 0) { /* Message is too long */ context->Corrupted = 1; } } if (context->Message_Block_Index == 64) { SHA1ProcessMessageBlock(context); } message_array++; } return shaSuccess; } /* * SHA1ProcessMessageBlock * * Description: * This function will process the next 512 bits of the message * stored in the Message_Block array. * * Parameters: * None. * * Returns: * Nothing. * * Comments: * Many of the variable names in this code, especially the * single character names, were used because those were the * names used in the publication. * * */ void SHA1ProcessMessageBlock(SHA1Context *context) { const uint32_t K[] = { /* Constants defined in SHA-1 */ 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 }; int t; /* Loop counter */ uint32_t temp; /* Temporary word value */ uint32_t W[80]; /* Word sequence */ uint32_t A, B, C, D, E; /* Word buffers */ /* * Initialize the first 16 words in the array W */ for(t = 0; t < 16; t++) { W[t] = context->Message_Block[t * 4] << 24; W[t] |= context->Message_Block[t * 4 + 1] << 16; W[t] |= context->Message_Block[t * 4 + 2] << 8; W[t] |= context->Message_Block[t * 4 + 3]; } for(t = 16; t < 80; t++) { W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); } A = context->Intermediate_Hash[0]; B = context->Intermediate_Hash[1]; C = context->Intermediate_Hash[2]; D = context->Intermediate_Hash[3]; E = context->Intermediate_Hash[4]; for(t = 0; t < 20; t++) { temp = SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } for(t = 20; t < 40; t++) { temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } for(t = 40; t < 60; t++) { temp = SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } for(t = 60; t < 80; t++) { temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } context->Intermediate_Hash[0] += A; context->Intermediate_Hash[1] += B; context->Intermediate_Hash[2] += C; context->Intermediate_Hash[3] += D; context->Intermediate_Hash[4] += E; context->Message_Block_Index = 0; } /* * SHA1PadMessage * * Description: * According to the standard, the message must be padded to an even * 512 bits. The first padding bit must be a '1'. The last 64 * bits represent the length of the original message. All bits in * between should be 0. This function will pad the message * according to those rules by filling the Message_Block array * accordingly. It will also call the ProcessMessageBlock function * provided appropriately. When it returns, it can be assumed that * the message digest has been computed. * * Parameters: * context: [in/out] * The context to pad * ProcessMessageBlock: [in] * The appropriate SHA*ProcessMessageBlock function * Returns: * Nothing. * */ void SHA1PadMessage(SHA1Context *context) { /* * Check to see if the current message block is too small to hold * the initial padding bits and length. If so, we will pad the * block, process it, and then continue padding into a second * block. */ if (context->Message_Block_Index > 55) { context->Message_Block[context->Message_Block_Index++] = 0x80; while(context->Message_Block_Index < 64) { context->Message_Block[context->Message_Block_Index++] = 0; } SHA1ProcessMessageBlock(context); while(context->Message_Block_Index < 56) { context->Message_Block[context->Message_Block_Index++] = 0; } } else { context->Message_Block[context->Message_Block_Index++] = 0x80; while(context->Message_Block_Index < 56) { context->Message_Block[context->Message_Block_Index++] = 0; } } /* * Store the message length as the last 8 octets */ context->Message_Block[56] = context->Length_High >> 24; context->Message_Block[57] = context->Length_High >> 16; context->Message_Block[58] = context->Length_High >> 8; context->Message_Block[59] = context->Length_High; context->Message_Block[60] = context->Length_Low >> 24; context->Message_Block[61] = context->Length_Low >> 16; context->Message_Block[62] = context->Length_Low >> 8; context->Message_Block[63] = context->Length_Low; SHA1ProcessMessageBlock(context); } bncsutil-1.4.5/src/bncsutil/sha1.h000066400000000000000000000040131523672167100167730ustar00rootroot00000000000000/* * sha1.h * * Description: * This is the header file for code which implements the Secure * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published * April 17, 1995. * * Many of the variable names in this code, especially the * single character names, were used because those were the names * used in the publication. * * Please read the file sha1.c for more information. * */ #ifndef _SHA1_H_ #define _SHA1_H_ #include #ifdef __cplusplus extern "C" { #endif /* * If you do not have the ISO standard stdint.h header file, then you * must typdef the following: * name meaning * uint32_t unsigned 32 bit integer * uint8_t unsigned 8 bit integer (i.e., unsigned char) * int_least16_t integer of >= 16 bits * */ #ifndef _SHA_enum_ #define _SHA_enum_ enum { shaSuccess = 0, shaNull, /* Null pointer parameter */ shaInputTooLong, /* input data too long */ shaStateError /* called Input after Result */ }; #endif #define SHA1HashSize 20 /* * This structure will hold context information for the SHA-1 * hashing operation */ typedef struct SHA1Context { uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ uint32_t Length_Low; /* Message length in bits */ uint32_t Length_High; /* Message length in bits */ /* Index into message block array */ int_least16_t Message_Block_Index; uint8_t Message_Block[64]; /* 512-bit message blocks */ int Computed; /* Is the digest computed? */ int Corrupted; /* Is the message digest corrupted? */ } SHA1Context; /* * Function Prototypes */ int SHA1Reset( SHA1Context *); int SHA1Input( SHA1Context *, const uint8_t *, unsigned int); int SHA1Result( SHA1Context *, uint8_t Message_Digest[SHA1HashSize]); #ifdef __cplusplus } // extern "C" #endif #endif bncsutil-1.4.5/src/bncsutil/stack.c000066400000000000000000000044611523672167100172460ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Stack * August 16, 2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ /** * Mule Server * Copyright (c) 2004-2006 Eric Naeseth. * * Stack * May 13, 2005 */ #include #include cm_stack_t cm_stack_create() { cm_stack_t stack = (cm_stack_t) calloc(1, sizeof(struct cm_stack)); if (!stack) return (cm_stack_t) 0; return stack; } void cm_stack_destroy(cm_stack_t stack) { cm_stack_node_t* node; cm_stack_node_t* next; if (!stack) return; node = stack->top; while (node) { next = node->next; free(node); node = next; } free(stack); } void cm_stack_push(cm_stack_t stack, void* item) { cm_stack_node_t* new_node; if (!stack || !item) return; new_node = (cm_stack_node_t*) malloc(sizeof(cm_stack_node_t)); if (!new_node) return; new_node->next = stack->top; new_node->value = item; stack->size++; stack->top = new_node; } void* cm_stack_pop(cm_stack_t stack) { cm_stack_node_t* next; void* value; if (!stack || !stack->top) return (void*) 0; next = stack->top->next; value = stack->top->value; free(stack->top); stack->top = next; stack->size--; return value; } void* cm_stack_peek(cm_stack_t stack) { if (!stack || !stack->top) return (void*) 0; return stack->top->value; } unsigned int cm_stack_size(cm_stack_t stack) { if (!stack) return 0; return stack->size; } bncsutil-1.4.5/src/bncsutil/stack.h000066400000000000000000000027351523672167100172550ustar00rootroot00000000000000/** * BNCSutil * Battle.Net Utility Library * * Copyright (C) 2004-2006 Eric Naeseth * * Stack * August 16, 2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * A copy of the GNU Lesser General Public License is included in the BNCSutil * distribution in the file COPYING. If you did not receive this copy, * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ /** * Mule Server * Copyright (c) 2004-2006 Eric Naeseth. * * Stack * May 13, 2005 */ #ifndef CM_STACK_H_INCLUDED #define CM_STACK_H_INCLUDED 1 typedef struct cm_stack_node { void* value; struct cm_stack_node* next; } cm_stack_node_t; typedef struct cm_stack { unsigned int size; cm_stack_node_t* top; } *cm_stack_t; cm_stack_t cm_stack_create(); void cm_stack_destroy(cm_stack_t stack); void cm_stack_push(cm_stack_t stack, void* item); void* cm_stack_pop(cm_stack_t stack); void* cm_stack_peek(cm_stack_t stack); unsigned int cm_stack_size(cm_stack_t stack); #endif bncsutil-1.4.5/vb6_example/000077500000000000000000000000001523672167100155665ustar00rootroot00000000000000bncsutil-1.4.5/vb6_example/.gitattributes000066400000000000000000000000311523672167100204530ustar00rootroot00000000000000* linguist-vendored=true bncsutil-1.4.5/vb6_example/BNCSutil.bas000066400000000000000000000306671523672167100177140ustar00rootroot00000000000000Attribute VB_Name = "BNCSutil" Option Explicit '------------------------------------------------------------------------------ ' BNCSutil ' Battle.Net Utility Library ' ' Copyright © 2004-2005 Eric Naeseth '------------------------------------------------------------------------------ ' Visual Basic Declarations ' November 20, 2004 '------------------------------------------------------------------------------ ' This library is free software; you can redistribute it and/or ' modify it under the terms of the GNU Lesser General Public ' License as published by the Free Software Foundation; either ' version 2.1 of the License, or (at your option) any later version. ' ' This library is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY; without even the implied warranty of ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ' Lesser General Public License for more details. ' ' A copy of the GNU Lesser General Public License is included in the BNCSutil ' distribution in the file COPYING. If you did not receive this copy, ' write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, ' Boston, MA 02111-1307 USA '------------------------------------------------------------------------------ ' DLL Imports '--------------------------- ' Library Information Public Declare Function bncsutil_getVersion Lib "bncsutil.dll" () As Long Public Declare Function bncsutil_getVersionString_Raw Lib "bncsutil.dll" _ Alias "bncsutil_getVersionString" (ByVal outBuf As String) As Long ' CheckRevision Public Declare Function extractMPQNumber Lib "bncsutil.dll" _ (ByVal mpqName As String) As Long ' [!] You should use checkRevision and getExeInfo (see below) instead of their ' _Raw counterparts. Public Declare Function checkRevision_Raw Lib "bncsutil.dll" Alias "checkRevisionFlat" _ (ByVal ValueString As String, ByVal File1 As String, ByVal File2 As String, _ ByVal File3 As String, ByVal mpqNumber As Long, ByRef Checksum As Long) As Long Public Declare Function getExeInfo_Raw Lib "bncsutil.dll" Alias "getExeInfo" _ (ByVal Filename As String, ByVal exeInfoString As String, _ ByVal infoBufferSize As Long, Version As Long, ByVal Platform As Long) As Long ' Old Logon System ' [!] You should use doubleHashPassword and hashPassword instead of their ' _Raw counterparts. (See below for those functions.) Public Declare Sub doubleHashPassword_Raw Lib "bncsutil.dll" Alias "doubleHashPassword" _ (ByVal Password As String, ByVal ClientToken As Long, ByVal ServerToken As Long, _ ByVal outBuffer As String) Public Declare Sub hashPassword_Raw Lib "bncsutil.dll" Alias "hashPassword" _ (ByVal Password As String, ByVal outBuffer As String) ' Broken SHA-1 Public Declare Sub calcHashBuf Lib "bncsutil.dll" _ (ByVal Data As String, ByVal Length As Long, ByVal Hash As String) ' CD-Key Decoding ' Call kd_init() first to set up the decoding system, unless you are only using kd_quick(). ' Then call kd_create() to create a key decoder "handle" each time you want to ' decode a CD-key. It will return the handle or -1 on failure. The handle ' should then be passed as the "decoder" argument to all the other kd_ functions. ' Call kd_free() on the handle when finished with the decoder to free the ' memory it is using. Public Declare Function kd_quick Lib "bncsutil.dll" _ (ByVal CDKey As String, ByVal ClientToken As Long, ByVal ServerToken As Long, _ PublicValue As Long, Product As Long, ByVal HashBuffer As String, ByVal BufferLen As Long) As Long Public Declare Function kd_init Lib "bncsutil.dll" () As Long Public Declare Function kd_create Lib "bncsutil.dll" _ (ByVal CDKey As String, ByVal keyLength As Long) As Long Public Declare Function kd_free Lib "bncsutil.dll" _ (ByVal decoder As Long) As Long Public Declare Function kd_val2Length Lib "bncsutil.dll" _ (ByVal decoder As Long) As Long Public Declare Function kd_product Lib "bncsutil.dll" _ (ByVal decoder As Long) As Long Public Declare Function kd_val1 Lib "bncsutil.dll" _ (ByVal decoder As Long) As Long Public Declare Function kd_val2 Lib "bncsutil.dll" _ (ByVal decoder As Long) As Long Public Declare Function kd_longVal2 Lib "bncsutil.dll" _ (ByVal decoder As Long, ByVal Out As String) As Long Public Declare Function kd_calculateHash Lib "bncsutil.dll" _ (ByVal decoder As Long, ByVal ClientToken As Long, ByVal ServerToken As Long) As Long Public Declare Function kd_getHash Lib "bncsutil.dll" _ (ByVal decoder As Long, ByVal Out As String) As Long Public Declare Function kd_isValid Lib "bncsutil.dll" _ (ByVal decoder As Long) As Long 'New Logon System ' Call nls_init() to get a "handle" to an NLS object (nls_init will return 0 ' if it encounters an error). This "handle" should be passed as the "NLS" ' argument to all the other nls_* functions. You do not need to change the ' username and password to upper-case as nls_init() will do this for you. ' Call nls_free() on the handle to free the memory it's using. ' nls_account_create() and nls_account_logon() generate the bodies of ' SID_AUTH_ACCOUNTCREATE and SID_AUTH_ACCOUNTLOGIN packets, respectively. Public Declare Function nls_init Lib "bncsutil.dll" _ (ByVal Username As String, ByVal Password As String) As Long 'really returns a POINTER! Public Declare Function nls_init_l Lib "bncsutil.dll" _ (ByVal Username As String, ByVal Username_Length As Long, _ ByVal Password As String, ByVal Password_Length As Long) As Long Public Declare Function nls_reinit Lib "bncsutil.dll" _ (ByVal NLS As Long, ByVal Username As String, ByVal Password As String) As Long Public Declare Function nls_reinit_l Lib "bncsutil.dll" _ (ByVal NLS As Long, ByVal Username As String, ByVal Username_Length As Long, _ ByVal Password As String, ByVal Password_Length As Long) As Long Public Declare Sub nls_free Lib "bncsutil.dll" _ (ByVal NLS As Long) Public Declare Function nls_account_create Lib "bncsutil.dll" _ (ByVal NLS As Long, ByVal Buffer As String, ByVal BufLen As Long) As Long Public Declare Function nls_account_logon Lib "bncsutil.dll" _ (ByVal NLS As Long, ByVal Buffer As String, ByVal BufLen As Long) As Long Public Declare Sub nls_get_A Lib "bncsutil.dll" _ (ByVal NLS As Long, ByVal Out As String) Public Declare Sub nls_get_M1 Lib "bncsutil.dll" _ (ByVal NLS As Long, ByVal Out As String, ByVal B As String, ByVal Salt As String) Public Declare Function nls_check_M2 Lib "bncsutil.dll" _ (ByVal NLS As Long, ByVal M2 As String, ByVal B As String, ByVal Salt As String) As Long Public Declare Function nls_check_signature Lib "bncsutil.dll" _ (ByVal Address As Long, ByVal Signature As String) As Long Public Declare Function nls_account_change_proof Lib "bncsutil.dll" _ (ByVal NLS As Long, ByVal Buffer As String, ByVal NewPassword As String, _ ByVal B As String, ByVal Salt As String) As Long 'returns a new NLS pointer for the new password Public Declare Sub nls_get_S Lib "bncsutil.dll" _ (ByVal NLS As Long, ByVal Out As String, ByVal B As String, ByVal Salt As String) Public Declare Sub nls_get_K Lib "bncsutil.dll" _ (ByVal NLS As Long, ByVal Out As String, ByVal S As String) Private Declare Function bncsutil_debug_status Lib "bncsutil.dll" () As Long Private Declare Function bncsutil_set_debug_status Lib "bncsutil.dll" (ByVal NewStatus As Long) As Long Private Declare Sub bncsutil_debug_message Lib "bncsutil.dll" (ByVal Message As String) Private Declare Sub bncsutil_debug_dump Lib "bncsutil.dll" (ByVal Message As String, ByVal Length As Long) Private Declare Function bncsutil_internal_debug_messages Lib "bncsutil.dll" () As Long ' Constants '--------------------------- Public Const BNCSUTIL_PLATFORM_X86& = &H1 Public Const BNCSUTIL_PLATFORM_WINDOWS& = &H1 Public Const BNCSUTIL_PLATFORM_WIN& = &H1 Public Const BNCSUTIL_PLATFORM_PPC& = &H2 Public Const BNCSUTIL_PLATFORM_MAC& = &H2 Public Const BNCSUTIL_PLATFORM_OSX& = &H3 ' Winsock '--------------------------- Private Type sockaddr_in Family As Integer Port As Integer Address As Long Filler As String * 8 End Type Private Declare Function getsockname Lib "ws2_32.dll" (ByVal S As Long, Name As sockaddr_in, NameLen As Long) As Long '---------------------------------------' ' VB-Specifc Functions and Properties ' '---------------------------------------' Public Property Get Version() As String Version = bncsutil_getVersionString() End Property Public Property Get DebugMode() As Boolean DebugMode = (bncsutil_debug_status() <> 0) End Property Public Property Let DebugMode(ByVal NewValue As Boolean) If (NewValue) Then bncsutil_set_debug_status 1 Else bncsutil_set_debug_status 0 End If End Property Public Property Get InternalDebugMessages() As Boolean InternalDebugMessages = (bncsutil_internal_debug_messages() <> 0) End Property Public Sub DebugMessage(Message As String) bncsutil_debug_message Message End Sub Public Sub DebugHexDump(Data As String, Optional ByVal Length As Long = -1) If (Length = -1) Then Length = Len(Data) End If bncsutil_debug_dump Data, Length End Sub ' RequiredVersion must be a version as a.b.c ' Returns True if the current BNCSutil version is sufficent, False if not. Public Function bncsutil_checkVersion(ByVal RequiredVersion As String) As Boolean Dim i&, j& Dim Frag() As String Dim Req As Long, Check As Long bncsutil_checkVersion = False Frag = Split(RequiredVersion, ".") j = 0 For i = UBound(Frag) To 0 Step -1 Check = Check + (CLng(Val(Frag(i))) * (100 ^ j)) j = j + 1 Next i Check = bncsutil_getVersion() If (Check >= Req) Then bncsutil_checkVersion = True End If End Function Public Function bncsutil_getVersionString() As String Dim S As String * 12 Dim Length As Long Length = bncsutil_getVersionString_Raw(S) bncsutil_getVersionString = Left$(S, Length) End Function 'CheckRevision Public Function checkRevision(ValueString As String, File1$, File2$, File3$, mpqNumber As Long, Checksum As Long) As Boolean checkRevision = (checkRevision_Raw(ValueString, File1, File2, File3, mpqNumber, Checksum) > 0) End Function Public Function checkRevisionA(ValueString As String, Files() As String, mpqNumber As Long, Checksum As Long) As Boolean checkRevisionA = (checkRevision_Raw(ValueString, Files(0), Files(1), Files(2), mpqNumber, Checksum) > 0) End Function 'EXE Information 'Information string (file name, date, time, and size) will be placed in InfoString. 'InfoString does NOT need to be initialized (e.g. InfoString = String$(255, vbNullChar)) 'Returns the file version or 0 on failure. Public Function getExeInfo(EXEFile As String, InfoString As String, Optional ByVal Platform As Long = BNCSUTIL_PLATFORM_WINDOWS) As Long Dim Version As Long, InfoSize As Long, Result As Long Dim i& InfoSize = 256 InfoString = String$(256, vbNullChar) Result = getExeInfo_Raw(EXEFile, InfoString, InfoSize, Version, Platform) If Result = 0 Then getExeInfo = 0 Exit Function End If While Result > InfoSize If InfoSize > 1024 Then getExeInfo = 0 Exit Function End If InfoSize = InfoSize + 256 InfoString = String$(InfoSize, vbNullChar) Result = getExeInfo_Raw(EXEFile, InfoString, InfoSize, Version, Platform) Wend getExeInfo = Version i = InStr(InfoString, vbNullChar) If i = 0 Then Exit Function InfoString = Left$(InfoString, i - 1) End Function 'OLS Password Hashing Public Function doubleHashPassword(Password As String, ByVal ClientToken&, ByVal ServerToken&) As String Dim Hash As String * 20 doubleHashPassword_Raw Password, ClientToken, ServerToken, Hash doubleHashPassword = Hash End Function Public Function hashPassword(Password As String) As String Dim Hash As String * 20 hashPassword_Raw Password, Hash hashPassword = Hash End Function Public Function nls_check_socket_signature(ByVal SocketHandle As Long, Signature As String) As Boolean Dim NameLen As Long, Name As sockaddr_in NameLen = 16 getsockname SocketHandle, Name, NameLen nls_check_socket_signature = (nls_check_signature(Name.Address, Signature) <> 0) End Function bncsutil-1.4.5/vb6_example/BNCSutilExample.vbp000066400000000000000000000021671523672167100212440ustar00rootroot00000000000000Type=Exe Form=frmMain.frm Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\WINDOWS\system32\STDOLE2.TLB#OLE Automation Object={248DD890-BB45-11CF-9ABC-0080C7E7B78D}#1.0#0; MSWINSCK.OCX Module=Connection; Connection.bas Module=Interface; Interface.bas Module=BNCSutil; BNCSutil.bas Class=Packet; Packet.cls Form=frmNewAccount.frm IconForm="frmMain" Startup="frmMain" HelpFile="" Title="BNCSutilExample" ExeName32="BNCSutilExample.exe" Command32="" Name="BNCSutilExample" HelpContextID="0" CompatibleMode="0" MajorVer=1 MinorVer=1 RevisionVer=0 AutoIncrementVer=0 ServerSupportFiles=0 VersionComments="BNCSutil Example Bot" VersionCompanyName="Cloaked" VersionFileDescription="BNCSutil Example Bot" VersionLegalCopyright="Placed in the public domain." VersionProductName="BNCSutil Example Bot" CompilationType=-1 OptimizationType=0 FavorPentiumPro(tm)=0 CodeViewDebugInfo=0 NoAliasing=0 BoundsCheck=0 OverflowCheck=0 FlPointCheck=0 FDIVCheck=0 UnroundedFP=0 StartMode=0 Unattended=0 Retained=0 ThreadPerObject=0 MaxNumberOfThreads=1 [MS Transaction Server] AutoRefresh=1 bncsutil-1.4.5/vb6_example/BNCSutilExample.vbw000066400000000000000000000003551523672167100212500ustar00rootroot00000000000000frmMain = 270, 18, 832, 605, Z, 0, 3, 414, 564, C Connection = 110, 120, 896, 520, Interface = 176, 192, 962, 592, BNCSutil = 22, 24, 808, 424, Packet = 0, 0, 786, 400, frmNewAccount = 110, 120, 896, 520, , 88, 96, 874, 496, C bncsutil-1.4.5/vb6_example/Connection.bas000066400000000000000000000665531523672167100203730ustar00rootroot00000000000000Attribute VB_Name = "Connection" Option Explicit '------------------------------------------------- ' Packet ID Constants '------------------------------------------------- Public Const SID_NULL& = &H0 Public Const SID_ENTERCHAT& = &HA Public Const SID_JOINCHANNEL& = &HC Public Const SID_CHATCOMMAND& = &HE Public Const SID_CHATEVENT& = &HF Public Const SID_UDPPINGRESPONSE& = &H14 Public Const SID_PING& = &H25 Public Const SID_LOGONRESPONSE& = &H29 Public Const SID_CREATEACCOUNT& = &H2A Public Const SID_CHANGEPASSWORD& = &H31 Public Const SID_LOGONRESPONSE2& = &H3A Public Const SID_CREATEACCOUNT2& = &H3D Public Const SID_AUTH_INFO& = &H50 Public Const SID_AUTH_CHECK& = &H51 Public Const SID_AUTH_ACCOUNTCREATE& = &H52 Public Const SID_AUTH_ACCOUNTLOGON& = &H53 Public Const SID_AUTH_ACCOUNTLOGONPROOF& = &H54 Public Const SID_AUTH_ACCOUNTCHANGE& = &H55 Public Const SID_AUTH_ACCOUNTCHANGEPROOF& = &H56 '------------------------------------------------- ' Product Constants '------------------------------------------------- Public Enum BNCSProducts STAR = &H53544152 ' in C: 'STAR' SEXP = &H53455850 ' in C: 'SEXP' W2BN = &H5732424E ' ... you get the idea D2DV = &H44324456 D2XP = &H44325850 WAR3 = &H57415233 W3XP = &H57335850 UNKN = &HFFFFFFFF ' unknown product End Enum Public Const ARCH_IX86 As Long = &H49583836 '------------------------------------------------- ' Status '------------------------------------------------- Public IsConnected As Boolean '------------------------------------------------- ' Connection Variables '------------------------------------------------- Private ClientToken As Long, ServerToken As Long, UseNLS As Boolean, _ NLS As Long, OldNLS As Long '------------------------------------------------- ' Misc. Windows API Declarations '------------------------------------------------- Public Declare Function GetTickCount Lib "kernel32.dll" () As Long '------------------------------------------------- ' Connector '------------------------------------------------- Public Sub Connect() ClientToken = GetTickCount() With frmMain .WS.Close .WS.RemoteHost = .txtServer .WS.RemotePort = 6112 .WS.Connect End With End Sub '------------------------------------------------- ' Disconnect '------------------------------------------------- Public Sub Disconnect() frmMain.WS.Close IsConnected = False ' Free NLS memory if still allocated. FreeNLS UpdateStatus "Disconnected." frmMain.cmdConnect.Caption = "Connect" End Sub Private Function HexByte(ByVal Number As Long) As String HexByte = Hex$(Number And &HFF) If Len(HexByte) = 1 Then _ HexByte = "0" & HexByte End Function '------------------------------------------------- ' First-Pass Data Handler '------------------------------------------------- ' Extracts all the packets from a particular ' chunk of data, and then passes each packet to ' the packet handler. '------------------------------------------------- Public Sub HandleData(Data As String, Length As Long) Dim Position As Long Dim P As Packet Dim PacketID As Byte Dim PacketLength As Long ' Initialize the packet buffer Set P = New Packet P.SetData Data Do While Position < Length ' All Battle.Net packets begin with a byte with a value ' of 0xFF. Make sure that the first byte we read is ' 0xFF, because if it's not, it's a sign that something ' went wrong. If (P.GetByte() <> &HFF) Then UpdateStatus "Error: Invalid Battle.Net packet received.", stError Disconnect Exit Sub End If PacketID = P.GetByte() PacketLength = P.GetWORD() BNCSutil.DebugMessage "Incoming Packet 0x" & HexByte(PacketID) & " (Length = " & PacketLength & ")" BNCSutil.DebugHexDump Data Select Case PacketID Case SID_AUTH_INFO HandleAuthInfo P Case SID_PING HandlePing P Case SID_AUTH_CHECK HandleAuthCheck P Case SID_AUTH_ACCOUNTLOGON HandleAuthLogon P Case SID_AUTH_ACCOUNTLOGONPROOF HandleAuthLogonProof P Case SID_LOGONRESPONSE2 HandleLogonResponse P Case SID_CHANGEPASSWORD HandleChangePassword P Case SID_CREATEACCOUNT2 HandleCreateAccount P Case SID_AUTH_ACCOUNTCHANGE HandleAuthChange P Case SID_AUTH_ACCOUNTCHANGEPROOF HandleAuthChangeProof P End Select ' Advance position. Position = Position + PacketLength Loop End Sub '------------------------------------------------- ' SID_AUTH_INFO (0x50) Sender '------------------------------------------------- Public Sub SendAuthInfo() Dim P As Packet, VerByte As Long, Client As Long Set P = New Packet ' Get client and check for success/failure. Client = GetClient() If (Client = 0) Then ' Failure. UpdateStatus "Invalid client.", stError Disconnect Exit Sub End If ' Determine version byte. Select Case Client Case STAR, SEXP VerByte = &HCD Case W2BN VerByte = &H4F Case D2DV, D2XP VerByte = &HB Case WAR3, W3XP VerByte = &H14 Case Else ' Just in case. UpdateStatus "Unknown client (when determining version byte).", stError Disconnect Exit Sub End Select ' Build and send packet. With P .InsertDWORD &H0 'Protocol ID (always zero) .InsertDWORD ARCH_IX86 'Platform ID (Intel x86) .InsertDWORD Client 'Game Client .InsertDWORD VerByte 'Version byte .InsertDWORD &H0 'Product Language .InsertDWORD &H0 'Local IP for Network Address Translation .InsertDWORD &H0 'Time zone bias .InsertDWORD &H0 'Locale ID .InsertDWORD &H0 'Language ID .InsertString "USA" 'Country abbreviation .InsertString "United States" 'Country .Send frmMain.WS, SID_AUTH_INFO End With End Sub Public Function KeyCount(ByVal Product As BNCSProducts) As Long Select Case Product Case D2XP, W3XP: KeyCount = 2 Case Else: KeyCount = 1 End Select End Function '------------------------------------------------- ' SID_AUTH_INFO (0x50) Handler '------------------------------------------------- Private Sub HandleAuthInfo(P As Packet) Dim mpqNumber As Long, ChecksumFormula As String Dim EXEVersion As Long, Checksum As Long, EXEInfo As String Dim HashFiles(2) As String Dim PublicValue As Long, ProductValue As Long Dim KeyHash As String * 20 Dim ServerSignature As String * 128 Dim NumberOfKeys As Long Dim i As Long Dim O As Packet Set O = New Packet Select Case P.GetDWORD() ' Logon type Case 0 'Old Logon System UseNLS = False Case 1 'W3 Beta NLS Disconnect MsgBox "The NLS revision that the server has requested " & _ "is not supported.", vbExclamation, "Example Bot" Exit Sub Case 2 'New Logon System UseNLS = True Case Else 'Who knows? Disconnect MsgBox "Unsupported logon system.", vbExclamation, "Example Bot" Exit Sub End Select ServerToken = P.GetDWORD() P.Skip 12 'Skip UDPvalue and MPQ filetime. mpqNumber = extractMPQNumber(P.GetString()) If (mpqNumber < 0) Then Disconnect MsgBox "Unrecognized MPQ number.", vbExclamation, "Example Bot" Exit Sub End If ChecksumFormula = P.GetString() ' Check server signature. ' (Appears broken?) 'If (UseNLS) Then ' ServerSignature = P.GetFixedString(128) ' If (Not nls_check_socket_signature(frmMain.WS.SocketHandle, ServerSignature)) Then ' Disconnect ' MsgBox "Server signature check failed.", vbExclamation, "Example Bot" ' End If 'End If ' Get hash file paths. GetHashFiles HashFiles ' Perform revision check operations. If (checkRevision(ChecksumFormula, HashFiles(0), HashFiles(1), _ HashFiles(2), mpqNumber, Checksum) = False) Then Disconnect MsgBox "CheckRevision failed.", vbExclamation, "Example Bot" Exit Sub End If ' Get EXE version info. EXEVersion = getExeInfo(HashFiles(0), EXEInfo) If (EXEVersion = 0) Then Disconnect MsgBox "Failed to get executable hash file information.", _ vbExclamation, "Example Bot" Exit Sub End If ' Build SID_AUTH_CHECK (0x51) packet. ' (We'll do the CD-key stuff along the way.) With O .InsertDWORD ClientToken .InsertDWORD EXEVersion .InsertDWORD Checksum ' Number of keys in packet: NumberOfKeys = KeyCount(GetClient()) .InsertDWORD NumberOfKeys .InsertDWORD 0 ' Not using spawn. ' Decode the CD-keys and calculate their hashes. For i = 0 To (NumberOfKeys - 1) If kd_quick(frmMain.txtCDKey(i).Text, ClientToken, ServerToken, PublicValue, ProductValue, KeyHash, 20) = 0 Then Disconnect MsgBox "Failed to decode CD key #" & (i + 1) & ".", vbExclamation, "Example Bot" Exit Sub End If .InsertDWORD Len(frmMain.txtCDKey(i).Text) .InsertDWORD ProductValue .InsertDWORD PublicValue .InsertDWORD 0 .InsertNonNTString KeyHash Next i ' Finishing touches. .InsertString EXEInfo .InsertString "BNCSutil Example" ' Key owner. .Send frmMain.WS, SID_AUTH_CHECK End With End Sub '------------------------------------------------- ' SID_PING (0x25) Handler '------------------------------------------------- Public Sub HandlePing(P As Packet) Dim O As Packet Set O = New Packet O.InsertDWORD P.GetDWORD() O.Send frmMain.WS, SID_PING End Sub '------------------------------------------------- ' SID_AUTH_CHECK (0x51) Handler '------------------------------------------------- Public Sub HandleAuthCheck(P As Packet) Dim strTmp As String Select Case P.GetDWORD() 'Result Case &H0 ' OK. Case &H100 Disconnect MsgBox "Game version is out of date. Wait for a BNLS update.", vbExclamation, "Example Bot" Exit Sub Case &H101 Disconnect MsgBox "Invalid game version.", vbExclamation, "Example Bot" Exit Sub Case &H200 Disconnect MsgBox "Invalid CD-Key.", vbExclamation, "Example Bot" Exit Sub Case &H201 Disconnect strTmp = P.GetString() If LenB(strTmp) > 0 Then MsgBox "CD-Key in use by " & strTmp & ".", vbExclamation, "Example Bot" Else MsgBox "CD-Key in use.", vbExclamation, "Example Bot" End If Exit Sub Case &H202 Disconnect MsgBox "CD-Key is banned from Battle.Net.", vbExclamation, "Example Bot" Exit Sub Case &H203 Disconnect MsgBox "CD-Key is for another game.", vbExclamation, "Example Bot" Exit Sub Case &H210 Disconnect MsgBox "Invalid Expansion CD-Key.", vbExclamation, "Example Bot" Exit Sub Case &H211 Disconnect strTmp = P.GetString() If LenB(strTmp) > 0 Then MsgBox "Expansion CD-Key in use by " & strTmp & ".", vbExclamation, "Example Bot" Else MsgBox "Expansion CD-Key in use.", vbExclamation, "Example Bot" End If Exit Sub Case &H212 Disconnect MsgBox "Expansion CD-Key is banned from Battle.Net.", vbExclamation, "Example Bot" Exit Sub Case &H213 Disconnect MsgBox "Expansion CD-Key is for another game.", vbExclamation, "Example Bot" Exit Sub Case Else Disconnect MsgBox "SID_AUTH_CHECK failed for an unknown reason.", vbExclamation, "Example Bot" End Select If frmMain.chkChangePassword.Value = vbChecked Then If UseNLS Then SendAuthChange Else SendChangePassword End If Else If UseNLS Then SendAuthLogon Else SendLogonResponse End If End If End Sub '------------------------------------------------- ' SID_AUTH_ACCOUNTLOGON (0x53) Sender '------------------------------------------------- Public Sub SendAuthLogon() Dim P As Packet Dim Var_A As String * 32 'note the * 32, this creates a 'fixed-length string 32 chars long Set P = New Packet ' The NLS variable is declared at the top of this module. ' Its value **MUST** remain available throughout all of the ' SID_AUTH_ACCOUNT* packets, which is why it's not declared ' in this sub. If you don't understatnd this, look into ' the concept of "variable scope". ' ' Note that the initialization is only done if NLS doesn't already have ' a value. This is because it will otherwise already have been created ' in the password change process. If (NLS = 0) Then NLS = nls_init(frmMain.txtUsername.Text, frmMain.txtPassword.Text) If (NLS = 0) Then Disconnect MsgBox "Failed to initialize NLS.", vbExclamation, "Example Bot" Exit Sub End If End If ' Retrieve "public ephermeral value" (A). Call nls_get_A(NLS, Var_A) ' Build packet. With P .InsertNonNTString Var_A .InsertString frmMain.txtUsername.Text ' Send away! .Send frmMain.WS, SID_AUTH_ACCOUNTLOGON End With End Sub '------------------------------------------------- ' SID_AUTH_ACCOUNTLOGON (0x53) Handler '------------------------------------------------- Public Sub HandleAuthLogon(P As Packet) Dim M1 As String * 20 Dim Salt As String, Var_B As String Dim O As Packet ' Examine result code. Select Case P.GetDWORD() Case 0 ' Logon accepted Case 1 ' Account doesn't exist. ShowAccountCreate 'If MsgBox("Account doesn't exist. Create account?", vbQuestion Or vbYesNo, "Example Bot") = vbYes Then ' SendAuthCreate 'Else ' Disconnect 'End If Exit Sub Case 5 ' Account requires upgrade. Disconnect MsgBox "Account requires upgrade.", vbExclamation, "Example Bot" Exit Sub Case Else ' ?? Disconnect MsgBox "Unknown logon result.", vbExclamation, "Example Bot" Exit Sub End Select ' Build SID_AUTH_ACCOUNTLOGONPROOF (0x54) packet. Set O = New Packet With P Salt = .GetFixedString(32) Var_B = .GetFixedString(32) End With ' Get password proof. Call nls_get_M1(NLS, M1, Var_B, Salt) With O .InsertNonNTString M1 .Send frmMain.WS, SID_AUTH_ACCOUNTLOGONPROOF End With End Sub '------------------------------------------------- ' SID_AUTH_ACCOUNTLOGONPROOF (0x54) Handler '------------------------------------------------- Public Sub HandleAuthLogonProof(P As Packet) ' Examine result. Dim M2 As String Select Case P.GetDWORD() Case 0 ' Check server password proof. M2 = P.GetFixedString(20) If (nls_check_M2(NLS, M2, vbNullString, vbNullString) = 0) Then Disconnect MsgBox "Server password proof check failed!", vbExclamation, "Example Bot" Exit Sub End If FreeNLS ' free NLS memory UpdateStatus "Logged in!" Case 2 Disconnect MsgBox "Incorrect password.", vbExclamation, "Example Bot" Exit Sub Case &HE Disconnect MsgBox "E-mail registration required.", vbExclamation, "Example Bot" Exit Sub Case Else Disconnect MsgBox "Unknown logon proof error.", vbExclamation, "Example Bot" Exit Sub End Select End Sub '------------------------------------------------- ' SID_AUTH_ACCOUNTCREATE (0x52) Sender '------------------------------------------------- Public Sub SendAuthCreate() Dim Buffer As String, BufLen As Long Dim P As Packet Set P = New Packet ' This one is pretty easy. BufLen = 65 + Len(frmMain.txtUsername.Text) Buffer = String$(BufLen, vbNullChar) ' Initialize buffer If (nls_account_create(NLS, Buffer, BufLen) = 0) Then Disconnect MsgBox "Failed to generate account create packet." Exit Sub End If With P .InsertNonNTString Buffer ' Buffer contains entire packet body. .Send frmMain.WS, SID_AUTH_ACCOUNTCREATE End With End Sub '------------------------------------------------- ' SID_AUTH_ACCOUNTCREATE (0x52) Handler '------------------------------------------------- Public Sub HandleAuthCreate(P As Packet) ' Examine result. Select Case P.GetDWORD() Case 0 UpdateStatus "Created account." Case 7, 8, 9, &HA, &HB, &HC Disconnect MsgBox "Invalid username.", vbExclamation, "Example Bot" Exit Sub Case Else Disconnect MsgBox "Account already exists.", vbExclamation, "Example Bot" Exit Sub End Select ' Now try logging in again. SendAuthLogon End Sub '------------------------------------------------- ' SID_LOGONRESPONSE2 (0x3A) Sender '------------------------------------------------- Public Sub SendLogonResponse() Dim P As Packet Set P = New Packet With P .InsertDWORD ClientToken .InsertDWORD ServerToken .InsertNonNTString doubleHashPassword(frmMain.txtPassword.Text, ClientToken, ServerToken) .InsertString frmMain.txtUsername.Text .Send frmMain.WS, SID_LOGONRESPONSE2 End With End Sub '------------------------------------------------- ' SID_LOGONRESPONSE2 (0x3A) Handler '------------------------------------------------- Public Sub HandleLogonResponse(P As Packet) ' Examine result. Select Case P.GetDWORD() Case 0 ' Success UpdateStatus "Logged in!" Case 1 ShowAccountCreate 'If (MsgBox("Account does not exist. Create account?", vbQuestion Or vbYesNo, "Example Bot") = vbYes) Then ' ' Create account. ' SendCreateAccount 'Else ' Disconnect 'End If Exit Sub Case 2 Disconnect MsgBox "Incorrect password.", vbExclamation, "Example Bot" Exit Sub End Select End Sub '------------------------------------------------- ' SID_CREATEACCOUNT2 (0x3D) Sender '------------------------------------------------- Public Sub SendCreateAccount() Dim P As Packet Set P = New Packet With P .InsertNonNTString hashPassword(frmMain.txtPassword.Text) .InsertString frmMain.txtUsername.Text .Send frmMain.WS, SID_CREATEACCOUNT2 End With End Sub '------------------------------------------------- ' SID_CREATEACCOUNT2 (0x3D) Handler '------------------------------------------------- Public Sub HandleCreateAccount(P As Packet) ' Examine result. Select Case P.GetDWORD() Case 0 ' Success UpdateStatus "Created account." Case 2 Disconnect MsgBox "Username contains invalid characters.", vbExclamation, "Example Bot" Exit Sub Case 3 Disconnect MsgBox "Username contains banned word(s).", vbExclamation, "Example Bot" Exit Sub Case 4 Disconnect MsgBox "Account already exists.", vbExclamation, "Example Bot" Exit Sub Case 6 Disconnect MsgBox "Username is too short.", vbExclamation, "Example Bot" Exit Sub Case Else Disconnect MsgBox "Unknown account creation result.", vbExclamation, "Example Bot" Exit Sub End Select ' Try logging in again, now that the account was created. SendLogonResponse End Sub '------------------------------------------------- ' SID_CHANGEPASSWORD (0x31) Sender '------------------------------------------------- Public Sub SendChangePassword() Dim P As Packet Set P = New Packet With P .InsertDWORD ClientToken .InsertDWORD ServerToken .InsertNonNTString doubleHashPassword(frmMain.txtPassword.Text, ClientToken, ServerToken) .InsertNonNTString hashPassword(frmMain.txtNewPassword.Text) .InsertString frmMain.txtUsername.Text .Send frmMain.WS, SID_CHANGEPASSWORD End With End Sub '------------------------------------------------- ' SID_CHANGEPASSWORD (0x31) Handler '------------------------------------------------- Public Sub HandleChangePassword(P As Packet) If (P.GetDWORD()) Then MsgBox "Password changed.", vbInformation, "BNCSutil Example Bot" Disconnect Else Disconnect UpdateStatus "Failed to change password.", stError End If End Sub '------------------------------------------------- ' SID_AUTH_ACCOUNTCHANGE (0x55) Sender '------------------------------------------------- Public Sub SendAuthChange() Dim P As Packet Set P = New Packet Dim A As String * 32 NLS = nls_init(frmMain.txtUsername.Text, frmMain.txtPassword.Text) If (NLS = 0) Then Disconnect MsgBox "Failed to initialize NLS.", vbExclamation, "Example Bot" Exit Sub End If With P Call nls_get_A(NLS, A) .InsertNonNTString A .InsertString frmMain.txtUsername.Text .Send frmMain.WS, SID_AUTH_ACCOUNTCHANGE End With End Sub '------------------------------------------------- ' SID_AUTH_ACCOUNTCHANGE (0x55) Handler '------------------------------------------------- Public Sub HandleAuthChange(P As Packet) Dim ServerKey As String, Salt As String, NewPW As String Dim NewNLS As Long, OutputBuffer As String * 84 Dim O As Packet Select Case P.GetDWORD() Case 0 'ok Case 1 Disconnect MsgBox "Account does not exist!", vbExclamation, "Example Bot" Exit Sub Case 5 Disconnect MsgBox "Account requires upgrade.", vbExclamation, "Example Bot" Exit Sub Case Else Disconnect MsgBox "Unknown SID_AUTH_ACCOUNTCHANGE response.", vbExclamation, "Example Bot" Exit Sub End Select Salt = P.GetFixedString(32) ServerKey = P.GetFixedString(32) NewPW = frmMain.txtNewPassword.Text NewNLS = nls_account_change_proof(NLS, OutputBuffer, NewPW, ServerKey, Salt) If (NewNLS = 0) Then Disconnect MsgBox "Failed to generate SID_AUTH_ACCOUNTCHANGEPROOF packet.", vbExclamation, "Example Bot" Exit Sub End If OldNLS = NLS NLS = NewNLS Set O = New Packet O.InsertNonNTString OutputBuffer O.Send frmMain.WS, SID_AUTH_ACCOUNTCHANGEPROOF End Sub '------------------------------------------------- ' SID_AUTH_ACCOUNTCHANGEPROOF (0x56) Handler '------------------------------------------------- Public Sub HandleAuthChangeProof(P As Packet) Dim M2 As String Select Case P.GetDWORD() Case 0 ' Check server password proof. M2 = P.GetFixedString(20) If (nls_check_M2(OldNLS, M2, vbNullString, vbNullString) = 0) Then ' note the OldNLS being used Disconnect MsgBox "Server password proof check failed!", vbExclamation, "Example Bot" End If ' Free NLS memory for old password. Call nls_free(OldNLS) OldNLS = 0 UpdateStatus "Password changed." SendAuthLogon ' log in Case 2 Disconnect MsgBox "Incorrect password!", vbExclamation, "Example Bot" Case Else Disconnect MsgBox "Unknown SID_AUTH_ACCOUNTCHANGEPROOF result code received.", vbExclamation, "Example Bot" End Select End Sub '------------------------------------------------- ' Account Create Request Accepted '------------------------------------------------- ' Called by frmNewAccount when the user presses ' the "Create Account" button and the confirmed ' password matches. '------------------------------------------------- Public Sub AccountCreateAccepted() If UseNLS Then SendAuthCreate Else SendCreateAccount End If End Sub '------------------------------------------------- ' Hash File Paths '------------------------------------------------- Public Sub GetHashFiles(Files() As String) Select Case GetClient() Case STAR, SEXP Files(0) = frmMain.txtHashFolder.Text & "\starcraft.exe" Files(1) = frmMain.txtHashFolder.Text & "\storm.dll" Files(2) = frmMain.txtHashFolder.Text & "\battle.snp" Case W2BN Files(0) = frmMain.txtHashFolder.Text & "\WarCraft II BNE.exe" Files(1) = frmMain.txtHashFolder.Text & "\storm.dll" Files(2) = frmMain.txtHashFolder.Text & "\battle.snp" Case D2DV, D2XP Files(0) = frmMain.txtHashFolder.Text & "\Game.exe" Files(1) = frmMain.txtHashFolder.Text & "\Bnclient.dll" Files(2) = frmMain.txtHashFolder.Text & "\D2Client.dll" Case WAR3, W3XP Files(0) = frmMain.txtHashFolder.Text & "\war3.exe" Files(1) = frmMain.txtHashFolder.Text & "\Storm.dll" Files(2) = frmMain.txtHashFolder.Text & "\Game.dll" End Select End Sub Private Sub FreeNLS() If (NLS <> 0) Then Call nls_free(NLS) NLS = 0 End If If (OldNLS <> 0) Then Call nls_free(OldNLS) OldNLS = 0 End If End Sub bncsutil-1.4.5/vb6_example/Interface.bas000066400000000000000000000135761523672167100201710ustar00rootroot00000000000000Attribute VB_Name = "Interface" Option Explicit '------------------------------------------------- ' Status Types '------------------------------------------------- Public Enum StatusTypes stNormal = 0 stError End Enum '------------------------------------------------- ' Folder Browsing API Declarations '------------------------------------------------- Private Type BrowseInfo hWndOwner As Long pidlRoot As Long sDisplayName As String sTitle As String ulFlags As Long lpfn As Long lParam As Long iImage As Long End Type Private Declare Function SHBrowseForFolder Lib "Shell32.dll" (bBrowse As BrowseInfo) As Long Private Declare Function SHGetPathFromIDList Lib "Shell32.dll" (ByVal lItem As Long, ByVal sDir As String) As Long '------------------------------------------------- ' Update Status '------------------------------------------------- Public Sub UpdateStatus(NewStatus As String, Optional ByVal sType As StatusTypes = stNormal) frmMain.lblStatus.Caption = NewStatus Select Case sType Case stNormal frmMain.lblStatus.ForeColor = vbButtonText Case stError frmMain.lblStatus.ForeColor = vbRed End Select End Sub '------------------------------------------------- ' Configuration Verifier '------------------------------------------------- ' Checks the fields on the form to make sure ' they have all been filled in properly. '------------------------------------------------- Public Function VerifyConfig() As Boolean VerifyConfig = False With frmMain If (.WS.State = sckConnected Or .WS.State = sckConnecting) Then Disconnect End If .cmdConnect.Enabled = False ' First, determine whether to enable ' the expansion CD-key field. If (KeyCount(GetClient()) = 2) Then .txtCDKey(1).Locked = False .txtCDKey(1).BackColor = vbWindowBackground .txtCDKey(1).ForeColor = vbWindowText Else .txtCDKey(1).Locked = True .txtCDKey(1).BackColor = vbButtonFace .txtCDKey(1).ForeColor = vbGrayText End If ' Check the config fields to see if something ' has been entered. If LenB(.txtUsername.Text) = 0 Then UpdateStatus "You must enter a username.", stError Exit Function End If If LenB(.txtPassword.Text) = 0 Then UpdateStatus "You must enter a password.", stError Exit Function End If If LenB(.txtCDKey(0).Text) = 0 Then UpdateStatus "You must enter a CD-key.", stError Exit Function End If If .txtCDKey(1).Locked = False And LenB(.txtCDKey(1).Text) = 0 Then UpdateStatus "You must enter an expansion CD-key.", stError Exit Function End If If LenB(.txtServer.Text) = 0 Then UpdateStatus "You must enter a server.", stError Exit Function End If If GetClient() = UNKN Then UpdateStatus "You must pick a client.", stError Exit Function End If If LenB(.txtHashFolder.Text) = 0 Then UpdateStatus "You must enter a hash folder.", stError Exit Function End If If .chkChangePassword.Value = vbChecked Then If LenB(.txtNewPassword.Text) = 0 Then UpdateStatus "You must enter a new password.", stError Exit Function End If If LenB(.txtNewPassword2.Text) = 0 Then UpdateStatus "You must confirm your password.", stError Exit Function End If If (.txtNewPassword.Text <> .txtNewPassword2.Text) Then UpdateStatus "The new password and its confirmation do not match.", stError Exit Function End If End If ' OK UpdateStatus "Ready to connect." .cmdConnect.Enabled = True VerifyConfig = True End With End Function '------------------------------------------------- ' Get Client Code '------------------------------------------------- ' Returns the Battle.Net product code (e.g. SEXP) ' for the client chosen on the form. '------------------------------------------------- Public Function GetClient() As BNCSProducts GetClient = frmMain.Product End Function '------------------------------------------------- ' Folder Browsing '------------------------------------------------- ' Let the user browse for a folder. Returns the ' selected folder or vbNullString on cancel. '------------------------------------------------- Public Function BrowseForFolder() As String Dim browse_info As BrowseInfo Dim item As Long Dim dir_name As String BrowseForFolder = vbNullString browse_info.hWndOwner = frmMain.hWnd browse_info.pidlRoot = 0 browse_info.sDisplayName = String$(260, vbNullChar) browse_info.sTitle = "Select Hash Directory" browse_info.ulFlags = 1 ' Return directory name. browse_info.lpfn = 0 browse_info.lParam = 0 browse_info.iImage = 0 item = SHBrowseForFolder(browse_info) If item Then dir_name = String$(260, vbNullChar) If SHGetPathFromIDList(item, dir_name) Then BrowseForFolder = Left(dir_name, InStr(dir_name, Chr$(0)) - 1) Else BrowseForFolder = vbNullString End If End If End Function '------------------------------------------------- ' Ask to Create Account '------------------------------------------------- Public Sub ShowAccountCreate() frmNewAccount.Show End Sub bncsutil-1.4.5/vb6_example/MSSCCPRJ.SCC000066400000000000000000000003101523672167100173360ustar00rootroot00000000000000[SCC] SCC=This is a source code control file [BNCSutilExample.vbp] SCC_Project_Name=this project is not under source code control SCC_Aux_Path= bncsutil-1.4.5/vb6_example/NLS.cls000066400000000000000000000052621523672167100167320ustar00rootroot00000000000000VERSION 1.0 CLASS BEGIN MultiUse = -1 'True Persistable = 0 'NotPersistable DataBindingBehavior = 0 'vbNone DataSourceBehavior = 0 'vbNone MTSTransactionMode = 0 'NotAnMTSObject END Attribute VB_Name = "NLS" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = False Attribute VB_Exposed = False Attribute VB_Ext_KEY = "SavedWithClassBuilder6" ,"Yes" Attribute VB_Ext_KEY = "Top_Level" ,"Yes" Option Explicit ' NLS Wrapper Class Private m_Username As String Private m_Password As String Private m_NLS As Long Private m_ServerKey As String Private m_Salt As String Private Sub Class_Terminate() On Error GoTo Trap If (m_NLS) Then _ nls_free m_NLS Trap: End Sub Public Property Get Username() As String Username = m_Username End Property Public Property Let Username(NewValue As String) m_Username = NewValue End Property Public Property Get Password() As String Password = m_Password End Property Public Property Let Password(NewValue As String) m_Password = NewValue End Property Public Property Get ServerKey() As String ServerKey = m_ServerKey End Property Public Property Let ServerKey(NewValue As String) m_ServerKey = NewValue End Property Public Property Get Salt() As String Salt = m_Salt End Property Public Property Let Salt(NewValue As String) m_Salt = NewValue End Property Public Property Get Handle() As Long If (m_NLS = 0 And LenB(m_Username) > 0 And LenB(m_Password) > 0) Then m_NLS = nls_init(m_Username, m_Password) End If Handle = m_NLS End Property Public Property Let Handle(ByVal NewValue As Long) If (m_NLS) Then _ nls_free m_NLS m_NLS = NewValue End Property Public Property Get PublicKey() As String PublicKey = String$(32, vbNullChar) nls_get_A Handle, PublicKey End Property Public Property Get ClientPasswordProof() As String ClientPasswordProof = String$(20, vbNullChar) nls_get_M1 Handle, ClientPasswordProof, m_ServerKey, m_Salt End Property Public Function VerifyServerProof(ServerProof As String) As Boolean If (nls_check_M2(Handle, ServerProof, vbNullString, vbNullString)) Then VerifyServerProof = True Else VerifyServerProof = False End If End Function Public Property Get CreateAccount() As Buffer Dim CreateBuf As String, DataLen As Long DataLen = Len(m_Username) + 65 CreateBuf = String$(DataLen, vbNullChar) Set CreateAccount = New Buffer With CreateAccount nls_account_create Handle, CreateBuf, DataLen .AddRaw CreateBuf End With End Property bncsutil-1.4.5/vb6_example/Packet.cls000066400000000000000000000214001523672167100174750ustar00rootroot00000000000000VERSION 1.0 CLASS BEGIN MultiUse = -1 'True Persistable = 0 'NotPersistable DataBindingBehavior = 0 'vbNone DataSourceBehavior = 0 'vbNone MTSTransactionMode = 0 'NotAnMTSObject END Attribute VB_Name = "Packet" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = True Attribute VB_PredeclaredId = False Attribute VB_Exposed = False Option Explicit Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (ByRef Destination As Any, ByRef Source As Any, ByVal numbytes As Long) Private Enum PacketType pIncoming pOutgoing pNull End Enum Public Enum PacketFormat pBnet pBNLS pMCP pNone pMatrix End Enum Private Const EOP_ERROR& = vbObjectError + 1201 Private RawData As String Private Mode As PacketType Public Position As Long Public RaiseOverflowErrors As Boolean Private Const RAISE_OVERFLOW_ERRORS_DEFAULT As Boolean = False Public Property Get EOPError() As Long EOPError = EOP_ERROR End Property Public Sub Reset() Mode = pNull RawData = "" Position = 1 End Sub Public Function SetData(Data As String) RawData = Data Mode = pIncoming End Function Public Function GetData() As String GetData = RawData Reset End Function Public Sub Skip(Bytes As Long) Position = Position + Bytes End Sub Public Function GetString() As String Dim NTPos&, strTemp$ GetString = "" NTPos = InStr(Position, RawData, vbNullChar) If NTPos = 0 Then If RaiseOverflowErrors Then _ Err.Raise EOP_ERROR, , "Trying to read past end of packet." Exit Function End If GetString = Mid$(RawData, Position, NTPos - Position) Position = NTPos + 1 End Function Public Function GetFixedString(Length As Long) As String Dim rVal& If LenData() - Position + 1 >= Length Then GetFixedString = Mid$(RawData, Position, Length) Position = Position + Length Else If RaiseOverflowErrors Then _ Err.Raise EOP_ERROR, , "Trying to read past end of packet." Exit Function End If End Function Public Function GetBoolean(Optional ByVal Bytes As Long = 4) As Boolean Dim rVal& If LenData() - Position + 1 >= Bytes Then CopyMemory rVal, ByVal Mid$(RawData, Position, Bytes), Bytes Position = Position + Bytes Else If RaiseOverflowErrors Then _ Err.Raise EOP_ERROR, , "Trying to read past end of packet." Exit Function End If If rVal = 0 Then GetBoolean = False Else GetBoolean = True End If End Function Public Function GetDWORD() As Long Dim rVal& If LenData() - Position + 1 >= 4 Then CopyMemory rVal, ByVal Mid$(RawData, Position, 4), 4 Position = Position + 4 GetDWORD = rVal 'BotEvent "", evDbg, Position & ":" & StrToHex(Mid$(RawData, Position)) Else If RaiseOverflowErrors Then _ Err.Raise EOP_ERROR, , "Trying to read past end of packet." Exit Function End If End Function Public Function GetDWORDArray(Length As Long) As Long() If Length = 0 Then Exit Function Dim oS() As Long, i& ReDim oS(Length) As Long For i = 0 To Length - 1 oS(i) = GetDWORD() Next i GetDWORDArray = oS End Function Public Function GetWORD() As Integer Dim rVal% If LenData() - Position + 1 >= 2 Then CopyMemory rVal, ByVal Mid$(RawData, Position, 2), 2 Position = Position + 2 GetWORD = rVal Else If RaiseOverflowErrors Then _ Err.Raise EOP_ERROR, , "Trying to read past end of packet." Exit Function End If End Function Public Function GetWORDArray(Length As Long) As Integer() If Length = 0 Then Exit Function Dim oS() As Integer, i& ReDim oS(Length) As Integer For i = 0 To Length - 1 oS(i) = GetWORD() Next i GetWORDArray = oS End Function Public Function GetByte() As Byte Dim rVal As Byte rVal = 0 If LenData() - Position + 1 >= 1 Then CopyMemory rVal, ByVal Mid$(RawData, Position, 1), 1 Position = Position + 1 GetByte = rVal Else If RaiseOverflowErrors Then _ Err.Raise EOP_ERROR, , "Trying to read past end of packet." GetByte = 0 End If End Function Public Function GetStringArray(ByVal Length As Long) As String() If Length = 0 Then Exit Function Dim oS() As String, i& ReDim oS(Length) As String For i = 0 To Length - 1 oS(i) = GetString() Next i GetStringArray = oS End Function Public Function LenData() As Long LenData = Len(RawData) End Function 'Used with Winsock.bas 'Public Function Send(Socket As Long, Optional PacketID As Byte, Optional ByVal Format As PacketFormat = pBnet) ' If Mode = pIncoming Then Exit Function ' Select Case Format ' Case pBnet ' SendData Socket, Chr$(&HFF) & MakeByte(PacketID) & _ ' MakeWORD(Len(RawData) + 4) & RawData ' Case pBNLS ' SendData Socket, MakeWORD(Len(RawData) + 3) & MakeByte(PacketID) & RawData ' Case pMCP ' SendData Socket, MakeWORD(Len(RawData) + 3) & MakeByte(PacketID) & RawData ' Case Else ' SendData Socket, RawData ' End Select ' Reset 'End Function Private Function HexByte(ByVal Number As Long) As String HexByte = Hex$(Number And &HFF) If Len(HexByte) = 1 Then _ HexByte = "0" & HexByte End Function 'Used with Winsock controls Public Sub Send(Socket As Winsock, Optional ByVal PacketID As Byte, Optional ByVal Format As PacketFormat = pBnet) On Error GoTo Trap Dim Data As String If Mode = pIncoming Then Exit Sub Select Case Format Case pBnet Data = Chr$(&HFF) & Chr$(PacketID) & _ MakeWORD(Len(RawData) + 4) & RawData Case pBNLS, pMCP Data = MakeWORD(Len(RawData) + 3) & Chr$(PacketID) & RawData Case pMatrix Data = MakeByte(PacketID) & Chr$(Len(RawData) + 3) & RawData Case Else Data = RawData End Select BNCSutil.DebugMessage "Outgoing Packet 0x" & HexByte(PacketID) & " (Length = " & Len(Data) & ")" BNCSutil.DebugHexDump Data Socket.SendData Data Reset Exit Sub Trap: On Error GoTo Trap2 Disconnect Trap2: End Sub Public Sub InsertString(Data As String) If Mode = pIncoming Then Exit Sub Mode = pOutgoing RawData = RawData & Data & Chr$(0) End Sub Public Sub InsertStringList(Data() As String) 'On Error Resume Next If Mode = pIncoming Then Exit Sub Mode = pOutgoing Dim i As Integer For i = LBound(Data) To UBound(Data) Step 1 RawData = RawData & Data(i) & Chr$(0) Next i RawData = RawData & Chr$(0) 'extra null byte to end stringlist End Sub Public Sub InsertStringArray(Data() As String) 'On Error Resume Next If Mode = pIncoming Then Exit Sub Mode = pOutgoing Dim i As Integer For i = LBound(Data) To UBound(Data) Step 1 RawData = RawData & Data(i) & Chr$(0) Next i 'no extra null byte in string arrays End Sub Public Sub InsertNTString(Data As String) InsertString Data End Sub Public Sub InsertNonNTString(Data As String) If Mode = pIncoming Then Exit Sub Mode = pOutgoing RawData = RawData & Data End Sub Public Sub InsertByte(Data As Byte) If Mode = pIncoming Then Exit Sub Mode = pOutgoing RawData = RawData & MakeByte(Data) End Sub Public Sub InsertWORD(Data As Integer) If Mode = pIncoming Then Exit Sub Mode = pOutgoing RawData = RawData & MakeWORD(Data) End Sub Public Sub InsertDWORD(Data As Long) If Mode = pIncoming Then Exit Sub Mode = pOutgoing RawData = RawData & MakeDWORD(Data) End Sub Public Sub InsertDWORDArray(Data() As Long) If Mode = pIncoming Then Exit Sub Mode = pOutgoing Dim i As Integer For i = LBound(Data) To UBound(Data) Step 1 RawData = RawData & MakeDWORD(Data(i)) Next i End Sub Private Function MakeByte(Data As Byte) As String Dim Result As String * 1 CopyMemory ByVal Result, Data, 1 MakeByte = Result End Function Private Function MakeWORD(Data As Integer) As String Dim Result As String * 2 CopyMemory ByVal Result, Data, 2 MakeWORD = Result End Function Public Function MakeDWORD(Data As Long) As String Dim Result As String * 4 CopyMemory ByVal Result, Data, 4 MakeDWORD = Result End Function Private Sub Class_Initialize() Position = 1 Mode = pNull RaiseOverflowErrors = RAISE_OVERFLOW_ERRORS_DEFAULT End Sub bncsutil-1.4.5/vb6_example/frmMain.frm000066400000000000000000000332441523672167100176730ustar00rootroot00000000000000VERSION 5.00 Object = "{248DD890-BB45-11CF-9ABC-0080C7E7B78D}#1.0#0"; "MSWINSCK.OCX" Begin VB.Form frmMain BorderStyle = 1 'Fixed Single Caption = "BNCSutil Example" ClientHeight = 6330 ClientLeft = 45 ClientTop = 360 ClientWidth = 5070 BeginProperty Font Name = "Tahoma" Size = 8.25 Charset = 0 Weight = 400 Underline = 0 'False Italic = 0 'False Strikethrough = 0 'False EndProperty LinkTopic = "Form1" MaxButton = 0 'False ScaleHeight = 6330 ScaleWidth = 5070 StartUpPosition = 3 'Windows Default Begin VB.Frame fraStatus Caption = "Status" Height = 855 Left = 120 TabIndex = 20 Top = 4200 Width = 4815 Begin VB.Label lblStatus Alignment = 2 'Center Height = 255 Left = 120 TabIndex = 21 Top = 360 Width = 4575 End End Begin VB.Frame fraConfig Caption = "Configuration" Height = 3375 Left = 120 TabIndex = 4 Top = 600 Width = 4815 Begin VB.TextBox txtNewPassword2 Height = 285 IMEMode = 3 'DISABLE Left = 1440 PasswordChar = "*" TabIndex = 25 Top = 3720 Width = 2535 End Begin VB.TextBox txtNewPassword Height = 285 IMEMode = 3 'DISABLE Left = 1440 PasswordChar = "*" TabIndex = 23 Top = 3360 Width = 2535 End Begin VB.CheckBox chkChangePassword Caption = "Change password when connected." Height = 255 Left = 120 TabIndex = 22 Top = 3000 Width = 3735 End Begin VB.CommandButton cmdBrowseHashes Caption = "Browse" Height = 255 Left = 3960 TabIndex = 19 Top = 2520 Width = 735 End Begin VB.TextBox txtHashFolder Height = 285 Left = 1320 TabIndex = 18 Top = 2520 Width = 2535 End Begin VB.TextBox txtServer Height = 285 Left = 1320 TabIndex = 14 Top = 1800 Width = 2535 End Begin VB.ComboBox cmbClient Height = 315 Left = 1320 Style = 2 'Dropdown List TabIndex = 16 Top = 2160 Width = 2535 End Begin VB.TextBox txtCDKey Height = 285 Index = 1 Left = 1320 TabIndex = 12 Top = 1440 Width = 2535 End Begin VB.TextBox txtCDKey Height = 285 Index = 0 Left = 1320 TabIndex = 10 Top = 1080 Width = 2535 End Begin VB.TextBox txtPassword Height = 285 IMEMode = 3 'DISABLE Left = 1320 PasswordChar = "*" TabIndex = 8 Top = 720 Width = 2535 End Begin VB.TextBox txtUsername Height = 285 Left = 1320 TabIndex = 6 Top = 360 Width = 2535 End Begin VB.Label lblNewPassword2 Caption = "Confirm:" Height = 255 Left = 120 TabIndex = 26 Top = 3750 Width = 975 End Begin VB.Label lblNewPassword Caption = "New Password:" Height = 255 Left = 120 TabIndex = 24 Top = 3390 Width = 1215 End Begin VB.Label Label9 Caption = "Hash Folder:" Height = 255 Left = 120 TabIndex = 17 Top = 2550 Width = 975 End Begin VB.Label Label8 Caption = "Server:" Height = 255 Left = 120 TabIndex = 13 Top = 1830 Width = 975 End Begin VB.Label Label7 Caption = "Client:" Height = 255 Left = 120 TabIndex = 15 Top = 2220 Width = 975 End Begin VB.Label Label5 Caption = "Expansion Key:" Height = 255 Left = 120 TabIndex = 11 Top = 1470 Width = 1215 End Begin VB.Label Label4 Caption = "CD-Key:" Height = 255 Left = 120 TabIndex = 9 Top = 1110 Width = 975 End Begin VB.Label Label3 Caption = "Password:" Height = 255 Left = 120 TabIndex = 7 Top = 750 Width = 975 End Begin VB.Label Label2 Caption = "Username:" Height = 255 Left = 120 TabIndex = 5 Top = 390 Width = 975 End End Begin VB.Frame fraButtons Height = 1095 Left = 0 TabIndex = 1 Top = 5280 Width = 8775 Begin VB.CheckBox chkDebug Caption = "Show BNCSutil debug messages." Height = 255 Left = 120 TabIndex = 27 Top = 720 Width = 2775 End Begin MSWinsockLib.Winsock WS Left = 2280 Top = 240 _ExtentX = 741 _ExtentY = 741 _Version = 393216 End Begin VB.CommandButton cmdConnect Caption = "Connect" Height = 375 Left = 120 TabIndex = 3 Top = 240 Width = 1215 End Begin VB.CommandButton cmdExit Caption = "Exit" Height = 375 Left = 3720 TabIndex = 2 Top = 240 Width = 1215 End End Begin VB.Label Label1 Caption = "A simple example of how to connect to Battle.Net using BNCSutil." Height = 255 Left = 120 TabIndex = 0 Top = 120 Width = 6135 End End Attribute VB_Name = "frmMain" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False Option Explicit Private ProductMap() As BNCSProducts Public Product As BNCSProducts Private Sub chkChangePassword_Click() If chkChangePassword.Value Then Height = 7605 fraConfig.Height = 4215 fraStatus.Top = 5040 fraButtons.Top = 6120 lblNewPassword.Visible = True lblNewPassword2.Visible = True txtNewPassword.Visible = True txtNewPassword2.Visible = True Else Height = 6765 fraConfig.Height = 3375 fraStatus.Top = 4200 fraButtons.Top = 5280 lblNewPassword.Visible = False lblNewPassword2.Visible = False txtNewPassword.Visible = False txtNewPassword2.Visible = False End If VerifyConfig End Sub Private Sub cmbChange() VerifyConfig End Sub Private Sub cmbClick() VerifyConfig End Sub Private Sub chkDebug_Click() BNCSutil.DebugMode = (chkDebug.Value = vbChecked) End Sub Private Sub cmbClient_Change() Dim Index As Long Index = cmbClient.ListIndex If Index < LBound(ProductMap) Or Index > UBound(ProductMap) Then ' sanity check Product = UNKN Exit Sub End If Product = ProductMap(Index) VerifyConfig End Sub Private Sub cmbClient_Click() cmbClient_Change End Sub Private Sub cmbClient_KeyPress(KeyAscii As Integer) cmbClient_Change End Sub Private Sub cmdExit_Click() Unload Me End Sub Private Sub Form_Load() On Error GoTo DLL_Error ' First, check that the BNCSutil library is ' available and recent enough to use. If (Not bncsutil_checkVersion("1.2.0")) Then MsgBox "The available BNCSutil library is too old to use. " & _ "BNCSutil 1.2.0 and up is required. (You have " & BNCSutil.Version & ".)", vbCritical, "Example Bot" End End If On Error GoTo Startup_Error ' Note: It is no longer necessary to call kd_init(). ' Add the list of clients. With frmMain.cmbClient .AddItem "StarCraft" .AddItem "Brood War" .AddItem "WarCraft II BNE" .AddItem "Diablo II" .AddItem "Lord of Destruction" .AddItem "WarCraft III" .AddItem "Frozen Throne" End With ' Set up combo box -> product code mapping ReDim ProductMap(6) As BNCSProducts ProductMap(0) = STAR ProductMap(1) = SEXP ProductMap(2) = W2BN ProductMap(3) = D2DV ProductMap(4) = D2XP ProductMap(5) = WAR3 ProductMap(6) = W3XP Product = UNKN chkChangePassword_Click ' "Verify" the fields (which will of course fail), ' setting up the Status label in the process. VerifyConfig ' If InternalDebugMessages is False, bncsutil.dll was ' not compiled with debugging messages. chkDebug.Enabled = BNCSutil.InternalDebugMessages If (BNCSutil.DebugMode) Then chkDebug.Value = vbChecked Else chkDebug.Value = vbUnchecked End If Exit Sub Startup_Error: ' Generic error. MsgBox "The bot failed to start. (" & Err.Description & " - #" & _ Err.Number & ")", vbCritical, "Example Bot" End Exit Sub DLL_Error: ' This code will be run if there was a problem ' calling bncsutil_checkVersion, indicating ' a problem with finding or loading the DLL. MsgBox "The BNCSutil library could not be loaded, and the bot must close.", _ vbCritical, "Example Bot" End End Sub Private Sub cmdBrowseHashes_Click() Dim Folder As String Folder = BrowseForFolder() If (Folder <> vbNullString) Then txtHashFolder.Text = Folder End If End Sub Private Sub cmdConnect_Click() If Not IsConnected Then UpdateStatus "Connecting..." cmdConnect.Caption = "Disconnect" Connect Else Disconnect End If End Sub Private Sub Form_Unload(Cancel As Integer) If (IsConnected) Then Disconnect End If If (BNCSutil.DebugMode) Then BNCSutil.DebugMode = False End If End Sub Private Sub txtCDKey_Change(Index As Integer) VerifyConfig End Sub Private Sub txtHashFolder_Change() VerifyConfig End Sub Private Sub txtHome_Change() VerifyConfig End Sub Private Sub txtNewPassword_Change() VerifyConfig End Sub Private Sub txtNewPassword2_Change() VerifyConfig End Sub Private Sub txtPassword_Change() VerifyConfig End Sub Private Sub txtServer_Change() VerifyConfig End Sub Private Sub txtUsername_Change() VerifyConfig End Sub Private Sub WS_Close() IsConnected = False UpdateStatus "Disconnected." cmdConnect.Caption = "Connect" End Sub Private Sub WS_Connect() IsConnected = True UpdateStatus "Connected." ' Let Battle.Net know that we're using the binary protocol. WS.SendData Chr$(1) ' Send SID_AUTH_INFO (0x50) SendAuthInfo End Sub Private Sub WS_DataArrival(ByVal bytesTotal As Long) Dim Data As String ' Get the data that was just received. WS.GetData Data, vbString ' Pass it to the first-pass parser. HandleData Data, bytesTotal End Sub 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) UpdateStatus "Socket Error: " & Description & " (#" & Number & ")", stError IsConnected = False cmdConnect.Caption = "Connect" End Sub bncsutil-1.4.5/vb6_example/frmNewAccount.frm000066400000000000000000000074471523672167100210630ustar00rootroot00000000000000VERSION 5.00 Begin VB.Form frmNewAccount BorderStyle = 3 'Fixed Dialog Caption = "Account Does Not Exist" ClientHeight = 2535 ClientLeft = 45 ClientTop = 360 ClientWidth = 5535 BeginProperty Font Name = "Tahoma" Size = 8.25 Charset = 0 Weight = 400 Underline = 0 'False Italic = 0 'False Strikethrough = 0 'False EndProperty Icon = "frmNewAccount.frx":0000 LinkTopic = "Form1" MaxButton = 0 'False MinButton = 0 'False ScaleHeight = 2535 ScaleWidth = 5535 ShowInTaskbar = 0 'False StartUpPosition = 3 'Windows Default Begin VB.TextBox txtConfirm Height = 285 IMEMode = 3 'DISABLE Left = 1800 PasswordChar = "*" TabIndex = 6 Top = 1410 Width = 3015 End Begin VB.Frame fraButtons Height = 975 Left = -240 TabIndex = 1 Top = 1800 Width = 6135 Begin VB.CommandButton cmdAbort Cancel = -1 'True Caption = "Abort" Height = 375 Left = 2760 TabIndex = 3 Top = 240 Width = 1215 End Begin VB.CommandButton cmdCreate Caption = "Create Account" Default = -1 'True Height = 375 Left = 4080 TabIndex = 2 Top = 240 Width = 1575 End End Begin VB.Label Label1 Caption = "Confirm Password:" Height = 255 Left = 120 TabIndex = 5 Top = 1440 Width = 1575 End Begin VB.Label lblStatus Caption = "If you would like to create the account, you must confirm your password." Height = 495 Left = 120 TabIndex = 4 Top = 720 Width = 5415 End Begin VB.Label lblQuestion Caption = "The account you have specified (""MMMMMMMMMMMMMMMM"") does not exist. What would you like to do?" Height = 495 Left = 120 TabIndex = 0 Top = 120 Width = 5295 End End Attribute VB_Name = "frmNewAccount" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False Option Explicit Private Sub cmdAbort_Click() Disconnect Unload Me End Sub Private Sub cmdCreate_Click() If LenB(txtConfirm.Text) = 0 Then lblStatus.ForeColor = vbRed lblStatus.Caption = "If you would like to create the account, you must confirm your password." Exit Sub End If If (frmMain.txtPassword.Text <> txtConfirm.Text) Then lblStatus.ForeColor = vbRed lblStatus.Caption = "The confirmation you entered does not match the password you previously entered." Exit Sub End If AccountCreateAccepted Unload Me End Sub Private Sub Form_Load() lblQuestion.Caption = "The account you have specified (""" & _ frmMain.txtUsername.Text & """) does not exist. What would you like to do?" lblStatus.ForeColor = vbButtonText lblStatus.Caption = "If you would like to create the account, you must confirm your password." End Sub bncsutil-1.4.5/vb6_example/frmNewAccount.frx000066400000000000000000000000141523672167100210550ustar00rootroot00000000000000lt