diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/XPKeygen.iml b/.idea/XPKeygen.iml deleted file mode 100644 index bc2cd87..0000000 --- a/.idea/XPKeygen.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 10bc744..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Keygen.vcxproj b/Keygen.vcxproj index 58e61ef..113ad88 100644 --- a/Keygen.vcxproj +++ b/Keygen.vcxproj @@ -64,8 +64,8 @@ <_ProjectFileVersion>10.0.20506.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\ + $(SolutionDir)build\$(Configuration)\ + build\$(Configuration)\intermediate\ $(ProjectName) $(ProjectName) .exe @@ -74,8 +74,8 @@ true true true - $(SolutionDir)$(Configuration)\ - $(Configuration)\ + $(SolutionDir)build\$(Configuration)\ + build\$(Configuration)\intermediate\ $(ProjectName) $(ProjectName) .exe @@ -85,6 +85,14 @@ true true + + $(SolutionDir)build\$(Configuration)\ + build\$(Configuration)\intermediate\ + + + $(SolutionDir)build\$(Configuration)\ + build\$(Configuration)\intermediate\ + $(IntDir) @@ -116,8 +124,8 @@ %(Filename)_p.c - lib\libcrypto.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - %(AdditionalLibraryDirectories) + crypt32.lib;ws2_32.lib;libcrypto.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + C:\Program Files\OpenSSL\lib;%(AdditionalLibraryDirectories) %(AdditionalOptions) /machine:x64 true @@ -164,8 +172,8 @@ %(Filename)_p.c - lib-x86\libcrypto.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - %(AdditionalLibraryDirectories) + crypt32.lib;ws2_32.lib;libcrypto.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + C:\Program Files (x86)\OpenSSL\lib;%(AdditionalLibraryDirectories) %(AdditionalOptions) true @@ -210,8 +218,8 @@ %(Filename)_p.c - lib\libcrypto.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - %(AdditionalLibraryDirectories) + crypt32.lib;ws2_32.lib;libcrypto.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + C:\Program Files\OpenSSL\lib;%(AdditionalLibraryDirectories) %(AdditionalOptions) /machine:x64 false %(IgnoreSpecificDefaultLibraries) @@ -255,8 +263,8 @@ %(Filename)_p.c - lib-x86\libcrypto.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - %(AdditionalLibraryDirectories) + crypt32.lib;ws2_32.lib;libcrypto.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + C:\Program Files (x86)\OpenSSL\lib;%(AdditionalLibraryDirectories) %(AdditionalOptions) false %(IgnoreSpecificDefaultLibraries) @@ -271,20 +279,6 @@ true - - - - - - - - - - - - - - @@ -297,6 +291,22 @@ + + + + + + + + + + + + + + + + diff --git a/Keygen.vcxproj.filters b/Keygen.vcxproj.filters index 03c29d4..de47111 100644 --- a/Keygen.vcxproj.filters +++ b/Keygen.vcxproj.filters @@ -1,36 +1,5 @@  - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Resources - - {174FAF7A-E150-316A-8FA9-DCB2D9FA4C51} @@ -71,7 +40,38 @@ - + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + Resources diff --git a/bin-x86/c_rehash.pl b/bin-x86/c_rehash.pl deleted file mode 100644 index a98cffd..0000000 --- a/bin-x86/c_rehash.pl +++ /dev/null @@ -1,252 +0,0 @@ -#!/usr/bin/env perl - -# WARNING: do not edit! -# Generated by makefile from tools\c_rehash.in -# Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. -# -# Licensed under the Apache License 2.0 (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - -# Perl c_rehash script, scan all files in a directory -# and add symbolic links to their hash values. - -my $dir = ""; -my $prefix = ""; - -my $errorcount = 0; -my $openssl = $ENV{OPENSSL} || "openssl"; -my $pwd; -my $x509hash = "-subject_hash"; -my $crlhash = "-hash"; -my $verbose = 0; -my $symlink_exists=eval {symlink("",""); 1}; -my $removelinks = 1; - -## Parse flags. -while ( $ARGV[0] =~ /^-/ ) { - my $flag = shift @ARGV; - last if ( $flag eq '--'); - if ( $flag eq '-old') { - $x509hash = "-subject_hash_old"; - $crlhash = "-hash_old"; - } elsif ( $flag eq '-h' || $flag eq '-help' ) { - help(); - } elsif ( $flag eq '-n' ) { - $removelinks = 0; - } elsif ( $flag eq '-v' ) { - $verbose++; - } - else { - print STDERR "Usage error; try -h.\n"; - exit 1; - } -} - -sub help { - print "Usage: c_rehash [-old] [-h] [-help] [-v] [dirs...]\n"; - print " -old use old-style digest\n"; - print " -h or -help print this help text\n"; - print " -v print files removed and linked\n"; - exit 0; -} - -eval "require Cwd"; -if (defined(&Cwd::getcwd)) { - $pwd=Cwd::getcwd(); -} else { - $pwd=`pwd`; - chomp($pwd); -} - -# DOS/Win32 or Unix delimiter? Prefix our installdir, then search. -my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':'; -$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : ""); - -if (! -x $openssl) { - my $found = 0; - foreach (split /$path_delim/, $ENV{PATH}) { - if (-x "$_/$openssl") { - $found = 1; - $openssl = "$_/$openssl"; - last; - } - } - if ($found == 0) { - print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n"; - exit 0; - } -} - -if (@ARGV) { - @dirlist = @ARGV; -} elsif ($ENV{SSL_CERT_DIR}) { - @dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR}; -} else { - $dirlist[0] = "$dir/certs"; -} - -if (-d $dirlist[0]) { - chdir $dirlist[0]; - $openssl="$pwd/$openssl" if (!-x $openssl); - chdir $pwd; -} - -foreach (@dirlist) { - if (-d $_ ) { - if ( -w $_) { - hash_dir($_); - } else { - print "Skipping $_, can't write\n"; - $errorcount++; - } - } -} -exit($errorcount); - -sub copy_file { - my ($src_fname, $dst_fname) = @_; - - if (open(my $in, "<", $src_fname)) { - if (open(my $out, ">", $dst_fname)) { - print $out $_ while (<$in>); - close $out; - } else { - warn "Cannot open $dst_fname for write, $!"; - } - close $in; - } else { - warn "Cannot open $src_fname for read, $!"; - } -} - -sub hash_dir { - my $dir = shift; - my %hashlist; - - print "Doing $dir\n"; - - if (!chdir $dir) { - print STDERR "WARNING: Cannot chdir to '$dir', $!\n"; - return; - } - - opendir(DIR, ".") || print STDERR "WARNING: Cannot opendir '.', $!\n"; - my @flist = sort readdir(DIR); - closedir DIR; - if ( $removelinks ) { - # Delete any existing symbolic links - foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) { - if (-l $_) { - print "unlink $_\n" if $verbose; - unlink $_ || warn "Can't unlink $_, $!\n"; - } - } - } - FILE: foreach $fname (grep {/\.(pem|crt|cer|crl)$/} @flist) { - # Check to see if certificates and/or CRLs present. - my ($cert, $crl) = check_file($fname); - if (!$cert && !$crl) { - print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n"; - next; - } - link_hash_cert($fname) if ($cert); - link_hash_crl($fname) if ($crl); - } - - chdir $pwd; -} - -sub check_file { - my ($is_cert, $is_crl) = (0,0); - my $fname = $_[0]; - - open(my $in, "<", $fname); - while(<$in>) { - if (/^-----BEGIN (.*)-----/) { - my $hdr = $1; - if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) { - $is_cert = 1; - last if ($is_crl); - } elsif ($hdr eq "X509 CRL") { - $is_crl = 1; - last if ($is_cert); - } - } - } - close $in; - return ($is_cert, $is_crl); -} - -sub compute_hash { - my $fh; - if ( $^O eq "VMS" ) { - # VMS uses the open through shell - # The file names are safe there and list form is unsupported - if (!open($fh, "-|", join(' ', @_))) { - print STDERR "Cannot compute hash on '$fname'\n"; - return; - } - } else { - if (!open($fh, "-|", @_)) { - print STDERR "Cannot compute hash on '$fname'\n"; - return; - } - } - return (<$fh>, <$fh>); -} - -# Link a certificate to its subject name hash value, each hash is of -# the form . where n is an integer. If the hash value already exists -# then we need to up the value of n, unless its a duplicate in which -# case we skip the link. We check for duplicates by comparing the -# certificate fingerprints - -sub link_hash_cert { - link_hash($_[0], 'cert'); -} - -# Same as above except for a CRL. CRL links are of the form .r - -sub link_hash_crl { - link_hash($_[0], 'crl'); -} - -sub link_hash { - my ($fname, $type) = @_; - my $is_cert = $type eq 'cert'; - - my ($hash, $fprint) = compute_hash($openssl, - $is_cert ? "x509" : "crl", - $is_cert ? $x509hash : $crlhash, - "-fingerprint", "-noout", - "-in", $fname); - chomp $hash; - $hash =~ s/^.*=// if !$is_cert; - chomp $fprint; - return if !$hash; - $fprint =~ s/^.*=//; - $fprint =~ tr/://d; - my $suffix = 0; - # Search for an unused hash filename - my $crlmark = $is_cert ? "" : "r"; - while(exists $hashlist{"$hash.$crlmark$suffix"}) { - # Hash matches: if fingerprint matches its a duplicate cert - if ($hashlist{"$hash.$crlmark$suffix"} eq $fprint) { - my $what = $is_cert ? 'certificate' : 'CRL'; - print STDERR "WARNING: Skipping duplicate $what $fname\n"; - return; - } - $suffix++; - } - $hash .= ".$crlmark$suffix"; - if ($symlink_exists) { - print "link $fname -> $hash\n" if $verbose; - symlink $fname, $hash || warn "Can't symlink, $!"; - } else { - print "copy $fname -> $hash\n" if $verbose; - copy_file($fname, $hash); - } - $hashlist{$hash} = $fprint; -} diff --git a/bin-x86/libcrypto-3.dll b/bin-x86/libcrypto-3.dll deleted file mode 100644 index a3e5256..0000000 Binary files a/bin-x86/libcrypto-3.dll and /dev/null differ diff --git a/bin-x86/libssl-3.dll b/bin-x86/libssl-3.dll deleted file mode 100644 index 7451337..0000000 Binary files a/bin-x86/libssl-3.dll and /dev/null differ diff --git a/bin-x86/openssl.exe b/bin-x86/openssl.exe deleted file mode 100644 index b62c01b..0000000 Binary files a/bin-x86/openssl.exe and /dev/null differ diff --git a/lib-x86/engines-3/capi.dll b/lib-x86/engines-3/capi.dll deleted file mode 100644 index cfcccea..0000000 Binary files a/lib-x86/engines-3/capi.dll and /dev/null differ diff --git a/lib-x86/engines-3/loader_attic.dll b/lib-x86/engines-3/loader_attic.dll deleted file mode 100644 index 7570e41..0000000 Binary files a/lib-x86/engines-3/loader_attic.dll and /dev/null differ diff --git a/lib-x86/engines-3/padlock.dll b/lib-x86/engines-3/padlock.dll deleted file mode 100644 index dc3f1d5..0000000 Binary files a/lib-x86/engines-3/padlock.dll and /dev/null differ diff --git a/lib-x86/libcrypto.lib b/lib-x86/libcrypto.lib deleted file mode 100644 index 1ba6091..0000000 Binary files a/lib-x86/libcrypto.lib and /dev/null differ diff --git a/lib-x86/libssl.lib b/lib-x86/libssl.lib deleted file mode 100644 index 49c40c5..0000000 Binary files a/lib-x86/libssl.lib and /dev/null differ diff --git a/lib-x86/ossl-modules/legacy.dll b/lib-x86/ossl-modules/legacy.dll deleted file mode 100644 index cf1cbd7..0000000 Binary files a/lib-x86/ossl-modules/legacy.dll and /dev/null differ diff --git a/lib/engines-3/capi.dll b/lib/engines-3/capi.dll deleted file mode 100644 index 3663a84..0000000 Binary files a/lib/engines-3/capi.dll and /dev/null differ diff --git a/lib/engines-3/capi.pdb b/lib/engines-3/capi.pdb deleted file mode 100644 index 0fa046a..0000000 Binary files a/lib/engines-3/capi.pdb and /dev/null differ diff --git a/lib/engines-3/loader_attic.dll b/lib/engines-3/loader_attic.dll deleted file mode 100644 index ed9bca4..0000000 Binary files a/lib/engines-3/loader_attic.dll and /dev/null differ diff --git a/lib/engines-3/loader_attic.pdb b/lib/engines-3/loader_attic.pdb deleted file mode 100644 index 424f7e1..0000000 Binary files a/lib/engines-3/loader_attic.pdb and /dev/null differ diff --git a/lib/engines-3/padlock.dll b/lib/engines-3/padlock.dll deleted file mode 100644 index 2e5a523..0000000 Binary files a/lib/engines-3/padlock.dll and /dev/null differ diff --git a/lib/engines-3/padlock.pdb b/lib/engines-3/padlock.pdb deleted file mode 100644 index 051abb4..0000000 Binary files a/lib/engines-3/padlock.pdb and /dev/null differ diff --git a/lib/libcrypto.lib b/lib/libcrypto.lib deleted file mode 100644 index 7ffaf98..0000000 Binary files a/lib/libcrypto.lib and /dev/null differ diff --git a/lib/libssl.lib b/lib/libssl.lib deleted file mode 100644 index 66fa1fc..0000000 Binary files a/lib/libssl.lib and /dev/null differ diff --git a/lib/ossl-modules/legacy.dll b/lib/ossl-modules/legacy.dll deleted file mode 100644 index 4d2b055..0000000 Binary files a/lib/ossl-modules/legacy.dll and /dev/null differ diff --git a/lib/ossl-modules/legacy.pdb b/lib/ossl-modules/legacy.pdb deleted file mode 100644 index 62236b4..0000000 Binary files a/lib/ossl-modules/legacy.pdb and /dev/null differ diff --git a/bink.cpp b/src/bink.cpp similarity index 100% rename from bink.cpp rename to src/bink.cpp diff --git a/header.h b/src/header.h similarity index 99% rename from header.h rename to src/header.h index a07067d..c292915 100644 --- a/header.h +++ b/src/header.h @@ -16,6 +16,8 @@ #include #include +#pragma warning(disable: 6387) + #define PK_LENGTH 25 #define NULL_TERMINATOR 1 diff --git a/key.cpp b/src/key.cpp similarity index 100% rename from key.cpp rename to src/key.cpp diff --git a/main.cpp b/src/main.cpp similarity index 100% rename from main.cpp rename to src/main.cpp diff --git a/resource.h b/src/resource.h similarity index 100% rename from resource.h rename to src/resource.h diff --git a/resource.rc b/src/resource.rc similarity index 100% rename from resource.rc rename to src/resource.rc diff --git a/server.cpp b/src/server.cpp similarity index 100% rename from server.cpp rename to src/server.cpp diff --git a/utilities.cpp b/src/utilities.cpp similarity index 100% rename from utilities.cpp rename to src/utilities.cpp diff --git a/windows.cpp b/src/windows.cpp similarity index 99% rename from windows.cpp rename to src/windows.cpp index c3fef0e..130fa8e 100644 --- a/windows.cpp +++ b/src/windows.cpp @@ -44,7 +44,7 @@ LRESULT HexEditProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_ } case WM_CHAR: { - WCHAR isXPresent[2 + 1]; // 0x and the NULL terminator. + WCHAR isXPresent[2 + 1]{}; // 0x and the NULL terminator. WCHAR hexNumber = toupper(wParam); ULONG hexLength = SendMessageW(hWindow, WM_GETTEXTLENGTH, 0, 0); @@ -198,7 +198,7 @@ LRESULT CALLBACK ComboProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam RECT rClient; PAINTSTRUCT paintStruct; - BITMAP pBitmap; + BITMAP pBitmap{}; HDC hClientDC = BeginPaint(hWindow, &paintStruct), hCompatDC = CreateCompatibleDC(hClientDC); @@ -722,7 +722,7 @@ LRESULT CALLBACK WNDProc(HWND hWindow, UINT uMessage, WPARAM wParam, LPARAM lPar /* Initialize system fonts. */ void InitializeFonts(HFONT *hLabelFont, HFONT *hSmolFont, HFONT *hBoldFont, HFONT *hCaptionFont) { - NONCLIENTMETRICSW nonClientMetrics; + NONCLIENTMETRICSW nonClientMetrics{}; // Get information about the default system font. nonClientMetrics.cbSize = sizeof(NONCLIENTMETRICSW); diff --git a/xp.cpp b/src/xp.cpp similarity index 100% rename from xp.cpp rename to src/xp.cpp diff --git a/BINKReader.py b/utilities/BINKReader.py similarity index 97% rename from BINKReader.py rename to utilities/BINKReader.py index e76d34c..9be4156 100644 --- a/BINKReader.py +++ b/utilities/BINKReader.py @@ -1,142 +1,142 @@ -import tkinter as tk -import os - -from colorama import init as colorama_init, Fore, Back, Style -from datetime import datetime as dt -from tkinter import filedialog - - -class TermColors: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKCYAN = '\033[96m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - - -def file_picker(): - print(f"{Style.BRIGHT}Please select a BINK resource file.{Style.RESET_ALL}") - - path = filedialog.askopenfilename( - parent=None, - title="Select a file", - filetypes=(("BINK resources", "*.bin"), ("All files", "*.*")) - ) - - if not path: - print(f"{Fore.RED}{Style.BRIGHT}Error: No file selected.{Style.RESET_ALL}") - exit(1) - - print(f"{Fore.LIGHTBLUE_EX}Loading file {path}...{Style.RESET_ALL}\n") - return path - - -def output_raw(bink_data, granularity=16): - byte_str = bink_data.hex(sep=' ', bytes_per_sep=1).upper() - p = list(map(''.join, zip(*[iter(byte_str)] * (granularity * 3)))) - - for i in range(len(p)): - p[i] = f"{Fore.GREEN}{Style.BRIGHT}0x{i * granularity:04X}{Style.RESET_ALL}: {p[i]}\n" - - print(f"{Fore.MAGENTA}{Style.BRIGHT}Raw BINK data:{Style.RESET_ALL}\n{''.join(p)}{Fore.YELLOW}--EOF--{Style.RESET_ALL} ({len(bink_data)} bytes)\n") - - -def validate_header(bink_header, bink_length): - sizeof = int.from_bytes(bink_header[0x04:0x08], byteorder='little') - countof = int.from_bytes(bink_header[0x08:0x0C], byteorder='little') - - # Windows XP - sizeof(BINKEY) == 0x016C && countof(BINKHDR) == 0x07 - # Windows Server 2003 - sizeof(BINKEY) == 0x01E4 && countof(BINKHDR) == 0x09 - if sizeof + 0x04 == bink_length and sizeof == 0x016C and countof == 0x07 or sizeof == 0x01E4 and countof == 0x09: - return True - - return False - - -def decode(bink_data): - bink_header = bink_data[:0x20] - bink_values = bink_data[0x20:] - - if not validate_header(bink_header, len(bink_data)): - print(f"{Fore.RED}{Style.BRIGHT}Error: Invalid BINK file.{Style.RESET_ALL}") - return - - output_raw(bink_data) - - identifier = int.from_bytes(bink_header[0x00:0x04], byteorder='little') - sizeof = int.from_bytes(bink_header[0x04:0x08], byteorder='little') - countof = int.from_bytes(bink_header[0x08:0x0C], byteorder='little') - checksum = int.from_bytes(bink_header[0x0C:0x10], byteorder='little') - version = int.from_bytes(bink_header[0x10:0x14], byteorder='little') - keysize = int.from_bytes(bink_header[0x14:0x18], byteorder='little') - hashlen = int.from_bytes(bink_header[0x18:0x1C], byteorder='little') - siglen = int.from_bytes(bink_header[0x1C:0x20], byteorder='little') - - server = countof == 0x09 - - print(f"{Fore.MAGENTA}{Style.BRIGHT}BINK header:{Style.RESET_ALL}") - - print(f"{Fore.LIGHTYELLOW_EX}Operating System:{Style.RESET_ALL}\t{'Windows Server 2003 / XP SP2 x64' if server else 'Windows 98 / XP x86'}{Style.RESET_ALL}") - print(f"{Fore.LIGHTYELLOW_EX}Identifier:{Style.RESET_ALL}\t\t\t0x{identifier:04X}{Style.RESET_ALL}") - print(f"{Fore.LIGHTYELLOW_EX}sizeof(BINKEY):{Style.RESET_ALL}\t\t{sizeof}{Style.RESET_ALL}") - print(f"{Fore.LIGHTYELLOW_EX}Header Length:{Style.RESET_ALL}\t\t{countof}{Style.RESET_ALL}") - print(f"{Fore.LIGHTYELLOW_EX}Checksum:{Style.RESET_ALL}\t\t\t0x{checksum:08X} ({checksum}){Style.RESET_ALL}") - print(f"{Fore.LIGHTYELLOW_EX}Creation Date:{Style.RESET_ALL}\t\t{dt(version // 10000, version // 100 % 100, version % 100, 0, 0)}{Style.RESET_ALL}") - print(f"{Fore.LIGHTYELLOW_EX}ECC Key Size:{Style.RESET_ALL}\t\t{keysize * 4 * 8} bits ({keysize} DWORDs){Style.RESET_ALL}") - print(f"{Fore.LIGHTYELLOW_EX}Hash Length:{Style.RESET_ALL}\t\t{hashlen} bits{Style.RESET_ALL}") - print(f"{Fore.LIGHTYELLOW_EX}Signature Length:{Style.RESET_ALL}\t{siglen} bits{Style.RESET_ALL}\n") - - # Windows Server 2003 uses an extended header format, meaning the content segment size and offset are different. - if server: - bink_header = bink_data[:0x28] - bink_values = bink_data[0x28:] - - authlen = int.from_bytes(bink_header[0x20:0x24], byteorder='little') - pidlen = int.from_bytes(bink_header[0x24:0x28], byteorder='little') - - print(f"{Fore.LIGHTYELLOW_EX}Auth Field Length:{Style.RESET_ALL}\t{authlen} bits{Style.RESET_ALL}") - print(f"{Fore.LIGHTYELLOW_EX}Product ID Length:{Style.RESET_ALL}\t{pidlen} bits{Style.RESET_ALL}\n") - - curve_params = { - 'p': 'Finite Field Order', - 'a': 'Curve Parameter', - 'b': 'Curve Parameter', - 'Gx': 'Base Point x-coordinate', - 'Gy': 'Base Point y-coordinate', - 'Kx': 'Public Key x-coordinate', - 'Ky': 'Public Key y-coordinate', - } - - print(f"{Fore.MAGENTA}{Style.BRIGHT}BINK Elliptic Curve Parameters:{Style.RESET_ALL}") - - offset = keysize * 4 - - for i, (x, y) in enumerate(curve_params.items()): - param = int.from_bytes(bink_values[i * offset:(i + 1) * offset], byteorder='little') - print(f"{Fore.LIGHTCYAN_EX}{y} {x}:{Style.RESET_ALL}\nHex: 0x{param:02X}\nDec: {param}{Style.RESET_ALL}\n") - - -def main(): - root = tk.Tk() - root.withdraw() - - print(f"{Style.BRIGHT}BINK Reader v1.0 by {Fore.MAGENTA}Endermanch{Style.RESET_ALL}\n") - - bink_path = file_picker() - - try: - with open(bink_path, "rb") as f: - decode(f.read()) - - except EnvironmentError: - print(f"{Fore.RED}{Style.BRIGHT}Error: Could not open BINK file.{Style.RESET_ALL}") - - -if __name__ == "__main__": - os.system('color') - main() - +import tkinter as tk +import os + +from colorama import init as colorama_init, Fore, Back, Style +from datetime import datetime as dt +from tkinter import filedialog + + +class TermColors: + HEADER = '\033[95m' + OKBLUE = '\033[94m' + OKCYAN = '\033[96m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + + +def file_picker(): + print(f"{Style.BRIGHT}Please select a BINK resource file.{Style.RESET_ALL}") + + path = filedialog.askopenfilename( + parent=None, + title="Select a file", + filetypes=(("BINK resources", "*.bin"), ("All files", "*.*")) + ) + + if not path: + print(f"{Fore.RED}{Style.BRIGHT}Error: No file selected.{Style.RESET_ALL}") + exit(1) + + print(f"{Fore.LIGHTBLUE_EX}Loading file {path}...{Style.RESET_ALL}\n") + return path + + +def output_raw(bink_data, granularity=16): + byte_str = bink_data.hex(sep=' ', bytes_per_sep=1).upper() + p = list(map(''.join, zip(*[iter(byte_str)] * (granularity * 3)))) + + for i in range(len(p)): + p[i] = f"{Fore.GREEN}{Style.BRIGHT}0x{i * granularity:04X}{Style.RESET_ALL}: {p[i]}\n" + + print(f"{Fore.MAGENTA}{Style.BRIGHT}Raw BINK data:{Style.RESET_ALL}\n{''.join(p)}{Fore.YELLOW}--EOF--{Style.RESET_ALL} ({len(bink_data)} bytes)\n") + + +def validate_header(bink_header, bink_length): + sizeof = int.from_bytes(bink_header[0x04:0x08], byteorder='little') + countof = int.from_bytes(bink_header[0x08:0x0C], byteorder='little') + + # Windows XP - sizeof(BINKEY) == 0x016C && countof(BINKHDR) == 0x07 + # Windows Server 2003 - sizeof(BINKEY) == 0x01E4 && countof(BINKHDR) == 0x09 + if sizeof + 0x04 == bink_length and sizeof == 0x016C and countof == 0x07 or sizeof == 0x01E4 and countof == 0x09: + return True + + return False + + +def decode(bink_data): + bink_header = bink_data[:0x20] + bink_values = bink_data[0x20:] + + if not validate_header(bink_header, len(bink_data)): + print(f"{Fore.RED}{Style.BRIGHT}Error: Invalid BINK file.{Style.RESET_ALL}") + return + + output_raw(bink_data) + + identifier = int.from_bytes(bink_header[0x00:0x04], byteorder='little') + sizeof = int.from_bytes(bink_header[0x04:0x08], byteorder='little') + countof = int.from_bytes(bink_header[0x08:0x0C], byteorder='little') + checksum = int.from_bytes(bink_header[0x0C:0x10], byteorder='little') + version = int.from_bytes(bink_header[0x10:0x14], byteorder='little') + keysize = int.from_bytes(bink_header[0x14:0x18], byteorder='little') + hashlen = int.from_bytes(bink_header[0x18:0x1C], byteorder='little') + siglen = int.from_bytes(bink_header[0x1C:0x20], byteorder='little') + + server = countof == 0x09 + + print(f"{Fore.MAGENTA}{Style.BRIGHT}BINK header:{Style.RESET_ALL}") + + print(f"{Fore.LIGHTYELLOW_EX}Operating System:{Style.RESET_ALL}\t{'Windows Server 2003 / XP SP2 x64' if server else 'Windows 98 / XP x86'}{Style.RESET_ALL}") + print(f"{Fore.LIGHTYELLOW_EX}Identifier:{Style.RESET_ALL}\t\t\t0x{identifier:04X}{Style.RESET_ALL}") + print(f"{Fore.LIGHTYELLOW_EX}sizeof(BINKEY):{Style.RESET_ALL}\t\t{sizeof}{Style.RESET_ALL}") + print(f"{Fore.LIGHTYELLOW_EX}Header Length:{Style.RESET_ALL}\t\t{countof}{Style.RESET_ALL}") + print(f"{Fore.LIGHTYELLOW_EX}Checksum:{Style.RESET_ALL}\t\t\t0x{checksum:08X} ({checksum}){Style.RESET_ALL}") + print(f"{Fore.LIGHTYELLOW_EX}Creation Date:{Style.RESET_ALL}\t\t{dt(version // 10000, version // 100 % 100, version % 100, 0, 0)}{Style.RESET_ALL}") + print(f"{Fore.LIGHTYELLOW_EX}ECC Key Size:{Style.RESET_ALL}\t\t{keysize * 4 * 8} bits ({keysize} DWORDs){Style.RESET_ALL}") + print(f"{Fore.LIGHTYELLOW_EX}Hash Length:{Style.RESET_ALL}\t\t{hashlen} bits{Style.RESET_ALL}") + print(f"{Fore.LIGHTYELLOW_EX}Signature Length:{Style.RESET_ALL}\t{siglen} bits{Style.RESET_ALL}\n") + + # Windows Server 2003 uses an extended header format, meaning the content segment size and offset are different. + if server: + bink_header = bink_data[:0x28] + bink_values = bink_data[0x28:] + + authlen = int.from_bytes(bink_header[0x20:0x24], byteorder='little') + pidlen = int.from_bytes(bink_header[0x24:0x28], byteorder='little') + + print(f"{Fore.LIGHTYELLOW_EX}Auth Field Length:{Style.RESET_ALL}\t{authlen} bits{Style.RESET_ALL}") + print(f"{Fore.LIGHTYELLOW_EX}Product ID Length:{Style.RESET_ALL}\t{pidlen} bits{Style.RESET_ALL}\n") + + curve_params = { + 'p': 'Finite Field Order', + 'a': 'Curve Parameter', + 'b': 'Curve Parameter', + 'Gx': 'Base Point x-coordinate', + 'Gy': 'Base Point y-coordinate', + 'Kx': 'Public Key x-coordinate', + 'Ky': 'Public Key y-coordinate', + } + + print(f"{Fore.MAGENTA}{Style.BRIGHT}BINK Elliptic Curve Parameters:{Style.RESET_ALL}") + + offset = keysize * 4 + + for i, (x, y) in enumerate(curve_params.items()): + param = int.from_bytes(bink_values[i * offset:(i + 1) * offset], byteorder='little') + print(f"{Fore.LIGHTCYAN_EX}{y} {x}:{Style.RESET_ALL}\nHex: 0x{param:02X}\nDec: {param}{Style.RESET_ALL}\n") + + +def main(): + root = tk.Tk() + root.withdraw() + + print(f"{Style.BRIGHT}BINK Reader v1.0 by {Fore.MAGENTA}Endermanch{Style.RESET_ALL}\n") + + bink_path = file_picker() + + try: + with open(bink_path, "rb") as f: + decode(f.read()) + + except EnvironmentError: + print(f"{Fore.RED}{Style.BRIGHT}Error: Could not open BINK file.{Style.RESET_ALL}") + + +if __name__ == "__main__": + os.system('color') + main() +