From f840b288398191fdbf2acdb13dd1cd3c6167ac22 Mon Sep 17 00:00:00 2001 From: Linus Probert Date: Mon, 11 Mar 2019 00:00:27 +0100 Subject: [PATCH] Adds mediocre crack protection - Added a simple checksum calculation lib - Validates the hardcoded "lib file" checksum against the calculated checksum. By looking at instructions for the cracked version of BreakHack on various sites that show up on google it seems that the common theme is to replace the steamlib dll/so with a modified version. Now the Steam version of the game will validate a hardcoded checksum against a live validated version to see if everything seems ok before boot. It's not a major hinderance but it should eliminate the more basic sites modus operandi. Honestly I don't really care if people steal the game. IT'S OPEN SOURCE FFS! And the above exclamation confirms why I did this. Also, I wanted to se if it was possible. Game on Crackers! :D --- .vimrc | 2 +- CMakeLists.txt | 3 ++ checksum/CMakeLists.txt | 33 ++++++++++++++++++++++ checksum/src/checksum.c | 61 +++++++++++++++++++++++++++++++++++++++++ checksum/src/checksum.h | 27 ++++++++++++++++++ src/defines.h | 4 +++ src/main.c | 30 ++++++++++++++++++++ 7 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 checksum/CMakeLists.txt create mode 100644 checksum/src/checksum.c create mode 100644 checksum/src/checksum.h diff --git a/.vimrc b/.vimrc index e3e881a..39419eb 100644 --- a/.vimrc +++ b/.vimrc @@ -5,5 +5,5 @@ nnoremap :ter ++close env LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./ ./_build/debu packadd termdebug let g:termdebug_wide = 1 -let g:syntastic_c_include_dirs = [ '_build/debug', '/usr/include/SDL2', 'steamworks_c_wrapper/src', 'physfs-3.0/src', 'bh_random/src' ] +let g:syntastic_c_include_dirs = [ '_build/debug', '/usr/include/SDL2', 'steamworks_c_wrapper/src', 'physfs-3.0/src', 'bh_random/src', 'checksum/src' ] let g:syntastic_cpp_include_dirs = [ 'steamworks_c_wrapper/sdk/public/steam', 'bh_random/src' ] diff --git a/CMakeLists.txt b/CMakeLists.txt index 61ad268..2b6e8d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ if (STEAM) add_subdirectory(steamworks_c_wrapper) endif() add_subdirectory(bh_random) +add_subdirectory(checksum) if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") set(CLANG 1) @@ -130,6 +131,7 @@ include_directories( ${LUA_INCLUDE_DIR} sqlite3 bh_random/src + checksum/src ) if (CMOCKA_FOUND) @@ -249,6 +251,7 @@ target_link_libraries(breakhack ${LUA_LIBRARIES} ${PHYSFS_LIBRARY} bh_random + checksum ) if (STEAM) diff --git a/checksum/CMakeLists.txt b/checksum/CMakeLists.txt new file mode 100644 index 0000000..6831492 --- /dev/null +++ b/checksum/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.1) +project(checksum C) + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif () + + +add_executable(checksumtool + src/checksum + ) +target_compile_definitions(checksumtool PUBLIC EXECUTABLE=1) + +add_library(checksum + src/checksum + ) + +IF ( MSVC ) + MESSAGE ( STATUS "Setting MSVC MT switches") + string (REPLACE + "/MDd" + "/MTd" + CMAKE_C_FLAGS_DEBUG + ${CMAKE_C_FLAGS_DEBUG} + ) + string (REPLACE + "/MDd" + "/MTd" + CMAKE_C_FLAGS_RELEASE + ${CMAKE_C_FLAGS_RELEASE} + ) +endif () + diff --git a/checksum/src/checksum.c b/checksum/src/checksum.c new file mode 100644 index 0000000..1248b13 --- /dev/null +++ b/checksum/src/checksum.c @@ -0,0 +1,61 @@ +/* +** CHECKSUM.C - Compute the checksum of a file +** +** public somain demo by Bob Stout +*/ + +#include +#include "checksum.h" + +unsigned +checksum(void *buffer, size_t len, unsigned int seed) +{ + unsigned char *buf = (unsigned char *)buffer; + size_t i; + + for (i = 0; i < len; ++i) + seed += (unsigned int)(*buf++); + return seed; +} + +unsigned +checksum_fp(FILE *fp) +{ + unsigned int seed = 0; + char buf[4096]; + + size_t len; + do { + len = fread(buf, sizeof(char), sizeof(buf), fp); + seed = checksum(buf, len, seed); + } while (len > 0); + + return seed; +} + +#ifdef EXECUTABLE +#include + +int main(int argc, char *argv[]) +{ + FILE *fp; + const char *file; + + if (argc < 2) { + printf("You need to provide an input file\n"); + printf("Example: %s ", argv[0]); + } + file = argv[1]; + + if (NULL == (fp = fopen(file, "rb"))) + { + printf("Unable to open %s for reading\n", file); + return -1; + } + + printf("The checksum of %s is %#x\n", file, checksum_fp(fp)); + + return 0; +} + +#endif diff --git a/checksum/src/checksum.h b/checksum/src/checksum.h new file mode 100644 index 0000000..cb10fd8 --- /dev/null +++ b/checksum/src/checksum.h @@ -0,0 +1,27 @@ +/* + * BreakHack - A dungeone crawler RPG + * Copyright (C) 2018 Linus Probert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +unsigned +checksum(void *buffer, size_t len, unsigned int seed); + +unsigned +checksum_fp(FILE *fp); diff --git a/src/defines.h b/src/defines.h index b3dd6ff..8fa82c7 100644 --- a/src/defines.h +++ b/src/defines.h @@ -22,6 +22,10 @@ #include #include "config.h" +/* Checksums */ +#define SO_LIBSTEAM_CHECKSUM 0x19ba253 +#define DLL_LIBSTEAM_CHECKSUM 0x19ba253 + /* Room/Map dimensions */ #define MAP_ROOM_WIDTH 16 #define MAP_ROOM_HEIGHT 12 diff --git a/src/main.c b/src/main.c index 02e9230..da8d6f6 100644 --- a/src/main.c +++ b/src/main.c @@ -57,6 +57,7 @@ #include "time.h" #include "sprite_util.h" #include "event.h" +#include "checksum.h" #ifdef STEAM_BUILD #include "steam/steamworks_api_wrapper.h" @@ -1361,10 +1362,39 @@ void close(void) SDL_Quit(); } +static void +validate_lib_checksum(void) +{ + FILE *fp; +#ifdef WIN32 + const char *file = "./libsteam_api.dll"; + unsigned int expected = DLL_LIBSTEAM_CHECKSUM; +#else + const char *file = "./libsteam_api.so"; + unsigned int expected = SO_LIBSTEAM_CHECKSUM; +#endif + + if (NULL == (fp = fopen(file, "rb"))) + { + fatal("Unable to open %s for reading\n", file); + } + unsigned calculated = checksum_fp(fp); + + if (calculated != expected) { + fatal("Checksum validation failiure: %#x != %#x", calculated, expected); + } else { + info("Checksum validated: %#x", calculated); + } +} + int main(int argc, char *argv[]) { UNUSED(argc); +#ifdef STEAM_BUILD + validate_lib_checksum(); +#endif // STEAM_BUILD + PHYSFS_init(argv[0]); #ifndef DEBUG PHYSFS_mount("assets.pack", NULL, 0);