Best way to obfuscate a Batch File?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
PaperTronics
Posts: 118
Joined: 02 Apr 2017 06:11

Re: Best way to obfuscate a Batch File?

#16 Post by PaperTronics » 05 Aug 2017 20:28

@aGerman - After the encryption, will the code be visible by any text editor or any hex editor? If not, then I'll start creating the login program right away!

@penpen - I tested both MD5 and AES and none seem to work for my friend. Sorry bro.


PaperTronics

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Best way to obfuscate a Batch File?

#17 Post by ShadowThief » 05 Aug 2017 21:51

PaperTronics wrote:@aGerman - After the encryption, will the code be visible by any text editor or any hex editor? If not, then I'll start creating the login program right away!

@penpen - I tested both MD5 and AES and none seem to work for my friend. Sorry bro.


PaperTronics

It's not encryption, it's obfuscation (sort of); the code is still easily seen in a hex editor.

The only secure way to store a password is to store a salted version of the password's hash and not the actual password.

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Best way to obfuscate a Batch File?

#18 Post by ShadowThief » 05 Aug 2017 22:02

I wrote this a while ago. It stores the password's salt and SHA-512 hash in a text file, but then turns that file into a hidden system file. As long as it's still in the same directory as the script, it can be read by the script. Sure, if the user knows where to look or has hidden/system files set to Visible they can see it, but most people don't. For added security, you could use AES.bat to encrypt the text file as well.

Code: Select all

@echo off
setlocal enabledelayedexpansion
cls

echo [R]egister new user
echo [L]og in with existing user
choice /C:RL /N >nul

if %errorlevel% equ 1 goto :register
if %errorlevel% equ 2 goto :login
exit /b

::------------------------------------------------------------------------------
:: Registers a user with an encrypted password.
::
:: Arguments: None
::------------------------------------------------------------------------------
:register
cls
set /p "register_user_name=Desired Username: "

if not exist accounts.txt (
   type nul >accounts.txt
   attrib +h +s accounts.txt
)

findstr /c:"!register_user_name!" accounts.txt 1>nul 2>&1 && (
   echo That user already has an account on this host. Exiting.
   pause
   exit /b
)

:setPassword
call :getPassword first_password "Desired Password: "
call :getPassword verify_password "Re-enter Password: "
if not "%first_password%"=="%verify_password%" (
   echo Passwords do not match. Please enter them again.
   echo/
   goto setPassword
) else (
   call :getSHA512 "!date!!time!" salt
   call :getSHA512 "!salt!!first_password!" passhash
)

>>accounts.txt echo %register_user_name% !salt! !passhash!
exit /b

::------------------------------------------------------------------------------
:: Logs in with a username and password
::
:: Arguments: None
::------------------------------------------------------------------------------
:login
cls
set /p "login_user_name=Username: "
call :getPassword given_pass "Password: "

findstr /c:"!login_user_name!" accounts.txt 1>nul 2>&1 || (
   echo Invalid username or password. Exiting.
   pause
   exit /b
)

for /f "tokens=1-3" %%A in ('findstr /c:"!login_user_name!" accounts.txt 2^>nul') do (
   set "stored_salt=%%B"
   set "stored_hash=%%C"
)


call :getSHA512 "!stored_salt!!given_pass!" givenpasshash
if not !givenpasshash!==!stored_hash! (
   echo Invalid username or password. Exiting.
) else (
   echo Login successful.
)

pause
exit /b

::------------------------------------------------------------------------------
:: Returns the SHA512 value of a string that has been echoed to a text file.
::
:: Arguments: %1 - the string to encode
::            %2 - the SHA512 value of %1
::------------------------------------------------------------------------------
:getSHA512
>shafile echo %~1
for /f "delims=" %%A in ('certutil -hashfile shafile SHA512 ^| find /v "hash"') do (
   set line=%%A
   set linehash=!line: =!
)
del shafile

set "%~2=!linehash!"
set "linehash="
goto :eof

::------------------------------------------------------------------------------
:: Hides user input and returns the input as a variable.
:: http://www.dostips.com/forum/viewtopic.php?p=33538#p33538 (and other places)
::
:: Arguments: %1 - the variable to store the password in
::            %2 - the prompt to display when receiving input
::------------------------------------------------------------------------------
:getPassword
set "_password="

:: We need a backspace to handle character removal
for /f %%a in ('"prompt;$H&for %%b in (0) do rem"') do set "BS=%%a"

:: Prompt the user
set /p "=%~2" <nul

:keyLoop
:: Retrieve a keypress
set "key="
for /f "delims=" %%a in ('xcopy /l /w "%~f0" "%~f0" 2^>nul') do if not defined key set "key=%%a"
set "key=%key:~-1%"

:: If No keypress (enter), then exit
:: If backspace, remove character from password and console
:: Otherwise, add a character to password and go ask for next one
if defined key (
    if "%key%"=="%BS%" (
        if defined _password (
         set "_password=%_password:~0,-1%"
      )
    ) else (
        set "_password=%_password%%key%"
        set /p "="<nul
    )
    goto :keyLoop
)
echo/

:: Return password to caller
set "%~1=%_password%"
goto :eof

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Best way to obfuscate a Batch File?

#19 Post by penpen » 06 Aug 2017 03:52

PaperTronics wrote:@penpen - I tested both MD5 and AES and none seem to work for my friend. Sorry bro.
Sorry for misleading you.

I gave the link to md5 (hash algorithm) and aes (de/encryption algorithm) to show, that both could be done in pure batch, so one would need no third party tools to create my above sketched algorithm; but don't get me wrong:
My sketched batch is not running code, but some kind of roadmap to show the principle of securely using username and password in hash (obfuscated user name (using md5 hash), no stored password).

I fear that algorithm is easily sketched, but there is still a lot of work left todo, and i currently have not much time.
In addition you said you are looking for obfuscated code, so my sketched batch seems to be some kind of (massive) overkill.
But feel free to finish the implementation process, if you like the basic idea.

ShadowThief wrote:It's not encryption, it's obfuscation (sort of); the code is still easily seen in a hex editor.
I think, i confused PaperTronics, with my theoretical scenario/example.

My sketeched algorithm would indeed encrypt the main part of the batch file (using the password), without the need to store the password in the above "sketched batch case":
The decrypted batch source part would probably be anything but meaningful batch code if you use the wrong decryption key (=password).

penpen

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Best way to obfuscate a Batch File?

#20 Post by aGerman » 06 Aug 2017 05:22

PaperTronics wrote:@aGerman - After the encryption, will the code be visible by any text editor or any hex editor?

There is no encryption in either of my proposals. Adding the UTF-16 BOM will only confuse text editors. It keeps perfectly readable in a HEX editor. Also working with variables is only obfuscation.

Steffen

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Best way to obfuscate a Batch File?

#21 Post by dbenham » 06 Aug 2017 16:35

Here is a batch script (with a dependency on JREPL.BAT) that does a good job of creating an obfuscated version of nearly any source batch script.
It obfuscates all code, :labels, variable names, and string constants. The resulting code is pure batch, yet it is completely unreadable, save for the first 5 lines that define a bunch of variables needed to run the obfuscated code.

But like any obfuscation, this is far from secure. It would not be hard to inject some ECHO OFF and PAUSE statements to expose the running code, and/or prefix some lines with ECHO to see some code.

Or a patient person could wade through the first 5 lines of code and deduce how to un-obfuscate the code. The remaining bit would be to crack the ROT13 cipher that is applied to labels and variable names, which is trivial.

It also would not be too difficult to write an UnObfuscateBatch.bat to restore the original source code, though I will not do so.

Never-the-less, this is still an interesting project.

Instructions for usage are embedded within the script. Included is a description of the algorithm, as well as the steps needed to properly prepare the source code for optimal obfuscation.

Edit 2017-08-31: Bug fix from penpen applied - Added dot to FOR /F delims and bumped version to 1.1
Edit 2017-10-11: Better obscured character mapping in obfuscated file, and bumped version to 1.2
ObfuscateBatch.bat

Code: Select all

:: ObfuscateBatch.bat  [/M]  SourceFile  [OutputFile]
::
::  Create obfuscated batch file OutputFile from SourceFile.
::
::  Note - This script requires JREPL.BAT v6.7 or higher.
::
::  If OutputFile is undefined, then the output file is named the same as
::  the base name of SourceFile, with _obfuscated appended, and the extension
::  is preserved.
::
::  For example:
::
::    obfuscate MyFile.cmd
::  
::  creates:
::
::    MyFile_obfuscated.cmd
::
::  There are two steps to the obfuscation:
::
::    Step 1)
::
::      - Text of the form {:Preserved} is preserved
::      - Text of the form {ROT13ObfuscatedText} has the ROT13 cipher applied
::        to alpha characters A-Z and a-z
::      - All other text is preserved
::
::    Step 2)       
::
::      - Text of the form {:Preserved} is preserved
::      - Text of the form {<Preserved} is preserved
::      - Labels :label are preserved
::      - Escaped percents %% are preserved
::      - "All arguments" %* is preserved
::      - Numbered arguments like %2 are preserved (including modifiers)
::      - All remaining lone percents % are preserved
::      - All remaining characters between \x20-\x7E are encoded as %HiByte%,
::        where HiByte represents an extended ASCII character between \xA1-\xFF
::
::    If the /M option is in effect, then text between { and }, or {: and },
::    or {< and } can span multiple lines.
::
::  The source file should consist of pure ASCII - no extended ASCII allowed.
::
::  For optimal obfuscation, the source code should adhere to these rules:
::
::    - Labels should be enclosed in braces:
::        :{Label}
::        goto {Label}
::        call :{Label}
::
::    - User defined variable names should be enclosed in braces:
::        set "{VarName}=value"
::        echo %{VarName}% or %{VarName}:find=replace%  etc.
::        echo !{VarName}! or !{VarName}:find=replace!  etc.
::
::    - Standard "variable" names like %comspec%, %random%, etc. should NOT be
::      enclosed in braces. Such variables will not be obfuscated. If possible,
::      use delayed  expansion instead. For eample - !comspec!, !random!, etc.
::      Variable names within delayed expansion are obfuscated.
::
::    - Text that should remain human readable within the resultant code should
::      be enclosed in {: }
::        {:This text is not obfuscated}
::
::    - Text that should have the ROT13 cipher applied, but not encoded as
::      %HiByte%, should be enclosed in {< }
::        {< This text has the ROT13 cipher applied only }
::
::    - Comments of the form %=Comment=% should be enclosed within braces
::        %={ ROT13 will be applied to this comment }=%
::
::    - Remember to use /M if text between braces spans multiple lines
::
::  When the obfuscated code is run, the current code page is stored, and the
::  code executes within a child cmd.exe process using code page 708. Any
::  command line arguments are passed without changes as long as all poison
::  characters are quoted. The use of escaped poison characters on the command
::  line is complicated and therefore discouraged.
::
::  Upon termination, the code page is restored to the original value and the
::  original environment is restored.
::
::  The use of code page 708 is somewhat arbitrary, except it is critical that
::  there not exist any extended ASCII character pairs that are recognized by
::  cmd.exe as upper/lower case pairs. Code page 708 happens to be the first
::  encoding I tested that passes this test.
::
::  ObfuscateBatch.bat v1.2 was written by Dave Benham and originally posted at
::  http://www.dostips.com/forum/viewtopic.php?f=3&t=7990&start=15#p53278

@echo off
setlocal disableDelayedExpansion
if /i "%~1" equ "/m" set "/m=/m" & shift /1
set "in=%~1"
if not defined in echo Error: Missing inputFile>&2&exit /b
set "out=%~2"
if not defined out set "out=%~dpn1_obfuscated%~x1"
set "find={[:<][^}]*}|^[^:\r\n]?[ \t=,;\xFF]*:[^ \t:\r\n+]*[ \t:\r\n+]?|%%%%|%%\*|%%(?:~[fdpnxsatz]*(?:\$[^:\r\n]+:)?)?[0-9]|%%[^%%\r\n]+%%|%%@[\x20-\x24\x26-\x7E]"
set "repl=$txt=$0@$txt='%%'+String.fromCharCode($0.charCodeAt(0)+129)+'%%'"

setlocal enableDelayedExpansion
set "str1="
set "x=x"
for %%A in (2 3 4 5 6 7) do @for %%B in (0 1 2 3 4 5 6 7 8 9 A B C D E F) do set "str1=!str1!\x%%A%%B"
set "str1=%str1:~0,-4%"
set "str1=%str1:\x22=%\x22"
set "str1=%str1:\x24\x25=DDDD%"
call jrepl x str1 /m /x /v /s x /rtn lo
set "lo=!lo:DDDD=$!"

set "str2="
for %%A in (A B C D E F) do @for %%B in (0 1 2 3 4 5 6 7 8 9 A B C D E F) do set "str2=!str2!\x%%A%%B"
set "str2=%str2:~4%"
set "str2=%str2:\xA3=%\xA3"
set "str2=%str2:\xA6=%"
call jrepl x str2 /m /x /v /s x /rtn hi
call jrepl "" "%%%%=%%%%" /m /x /s hi /rtn hi2

call :write <"!in!" >"!out!"
exit /b

:write
echo @echo off^&(if defined @lo@ goto !hi:~0,1!)^&setlocal disableDelayedExpansion^&for /f "delims=:. tokens=2" %%%%A in ('chcp') do set "@chcp@=chcp %%%%A>nul"^&chcp 708^>nul^&set ^^^^"@args@=%%*"
echo set "@lo@=!lo!"
echo set "@hi@=!hi2!"
echo (setlocal enableDelayedExpansion^&for /l %%%%N in (0 1 93) do set "^!@hi@:~%%%%N,1^!=^!@lo@:~%%%%N,1^!")^&cmd /c ^^^^^""%%~f0" ^^!@args@^^!"
echo %%@chcp@%%^&exit /b
echo :!hi:~0,1!
jrepl "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"^
      "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM"^
      %/m% /t "" /p "{[^:}][^}]*}" | jrepl find repl %/m% /t @ /v /x /jq
exit /b
As a test, I decided to fully obfuscate my batchMasterMind.bat.
I took the time to put braces around all my labels and variable names to get optimal obfuscation, as well as special braces around the header description comments to keep them readable.
No other changes were made to the source. Here is the source:

batchMasterMind.bat (source file)

Code: Select all

::{:
:: BatchMasterMind.bat
::
:: Version History
:: 1.0  2014-12-31  - Original release
:: 2.0  2015-01-02  - Added menu for different rule variations
::                  - Added error message for invalid guess
::
:: Written by Dave Benham and Originally posted at
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=6153
::}
@echo off
setlocal enableDelayedExpansion

:{mainMenu}
cls
echo(
echo(M - Mastermind       (code length 4, 6 symbols, 10 guesses)
echo(S - Super Mastermind (code length 5, 8 symbols, 12 guesses)
echo(C - Custom
echo(Q - Quit
echo(
<nul set /p "=> "
call :{getKey} MSCQ {key}
if /i !{key}! equ Q (
  echo Q
  echo(
  exit/b
) else if /i !{key}! equ M (
  set "{symbols}=123456"
  set "{maxGuesses}=10"
  set "{codeLen}=4"
  set "{dups}=Y"
) else if /i !{key}! equ S (
  set "{symbols}=12345678"
  set "{maxGuesses}=12"
  set "{codeLen}=5"
  set "{dups}=Y"
) else %={ key equ C }=% (
  call :{custom}
)

:: Initialize
set "{matchPosSymbol}=X"
set "{matchSymSymbol}=O"
set "{noMatchSymbol}=-"
set "{maskSymbol}=-"
call :{strlen} {symbols} {symbolCnt}
set /a {codeStop}={codeLen}-1
set "{noMatch}="
set "{mask}="
for /l %%N in (1 1 %{codeLen}%) do (
  set "{noMatch}=!{noMatch}!%{noMatchSymbol}%"
  set "{mask}=!{mask}!!{maskSymbol}!"
)

:: Show Help
cls
echo(
echo You have %{maxGuesses}% guesses to deduce the %{codeLen}% character code
echo consisting of any combination of the following symbols:
echo(
echo   !{symbols}!
echo(
if /i !{dups}! equ Y (
  echo Duplicate symbols are allowed in the code.
) else (
  echo Duplicate symbols are NOT allowed in the code.
)
echo(
echo The number of !{matchPosSymbol}! characters tells you how many symbols
echo match and are in the correct position.
echo(
echo The number of !{matchSymSymbol}! characters tells you how many symbols
echo match but are in the wrong position.
echo(
pause

:{play}

:: GetCode
set "{list}=!{symbols}!"
set "{len}=%{symbolCnt}%"
set "{code}="
for /l %%N in (0 1 %{codeStop}%) do (
  set /a "n=!random!%%{len}"
  for %%A in (!n!) do (
    set "{code}=!{code}!!{list}:~%%A,1!"
    if /i !{dups}! equ N (
      set /a "n+=1, {len}-=1"
      for %%B in (!n!) do set "{list}=!{list}:~0,%%A!!{list}:~%%B!"
    )
  )
)

:: ClearTurns
for /l %%N in (1 1 %{maxGuesses}%) do if %%N lss 10 (
  set "{turn}[%%N]=  %%N"
) else (
  set "{turn}[%%N]= %%N"
)

:: Turn Loop
for /l %%T in (%{maxGuesses}% -1 1) do (

  call :{showBoard} {mask}
  call :{getGuess}

  %={ Compute Score }=%
  for /l %%A in (0 1 %{codeStop}%) do (
    set "{guess}[%%A]=!{guess}:~%%A,1!"
    set "{code}[%%A]=!{code}:~%%A,1!"
  )
  set "{matchPos}="
  for /l %%A in (0 1 %{codeStop}%) do if !{guess}[%%A]! equ !{code}[%%A]! (
    set "{matchPos}=!{matchPos}!!{matchPosSymbol}!"
    set "{guess}[%%A]="
    set "{code}[%%A]="
  )
  set "{matchSym}="
  for /l %%A in (0 1 %{codeStop}%) do for /l %%B in (0 1 %{codeStop}%) do if defined {guess}[%%A] if !{guess}[%%A]! equ !{code}[%%B]! (
    set "{matchSym}=!{matchSym}!!{matchSymSymbol}!"
    set "{guess}[%%A]="
    set "{code}[%%B]="
  )
  set "{score}=!{matchPos}!!{matchSym}!!{noMatch}!"
  set "{score}=!{score}:~0,%{codeLen}%!"

  %={ Define Turn }=%
  set "{turn}[%%T]=!{turn}[%%T]!   !{guess}!  !{score}!"

  %={ Check for winner }=%
  if !{guess}! equ !{code}! goto :{endGame}
)


:{endGame}
call :{showBoard} {code}
if !{guess}! equ !{code}! (echo You WIN^^!) else (echo You LOSE^^!)
echo(
<nul set /p "=Play again [YN]? "
call :{getKey} YN {key}
if /i !{key}! equ Y goto :{play}
goto :{mainMenu}


:{badGuess}
echo Invalid guess - Must have length %{codeLen}% with valid symbols only

:{getGuess}
set "{guess}="
set /p "{guess}=Guess "
if not defined {guess} goto :{badGuess}
for /f "delims=%{symbols}% eol=%{symbols}:~0,1%" %%A in ("%{guess}%") do goto :{badGuess}
if "!{guess}:~%{codeLen}%!" neq "" goto :{badGuess}
if "!{guess}:~%{codeStop}%!" equ "" goto :{badGuess}
exit /b


:{showBoard}  target
cls
echo(
echo       !%1!  [!{symbols}!]
echo(
for /l %%N in (%{maxGuesses}% -1 1) do echo !{turn}[%%N]!
echo(
exit /b


:{strlen}  StrVar  RtnVar
setlocal enableDelayedExpansion
set "s=!%~1!#"
set "{len}=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
  if "!s:~%%P,1!" NEQ "" (
      set /a "{len}+=%%P"
      set "s=!s:~%%P!"
  )
)
endlocal & set "%~2=%{len}%"
exit /b


:{custom}
cls
echo(

:{getSymbols}
set "{symbols}="
set /p "{symbols}=Symbols = "
if not defined {symbols} goto :{getSymbols}

:{getCodeLen}
set "{codeLen}="
set /p "{codeLen}=Code length = "
2>nul set /a {codeLen}={codeLen} || goto :{getCodeLen}
if %{codeLen}% lss 1 goto :{getCodeLen}

<nul set /p "=Allow duplicate symbols in code? [YN] "
call :{getKey} YN {dups}
echo !{dups}!

:{getMaxGuesses}
set "{maxGuesses}="
set /p "{maxGuesses}=Max guesses = "
2>nul set /a {maxGuesses}={maxGuesses} || goto :{getMaxGuesses}
if %{maxGuesses}% lss 1 goto :{getMaxGuesses}
exit /b


:{getKey}  validList  rtnVar
setlocal
set "{valid}=%~1"
set "{key}="
for /f "delims=" %%A in ('xcopy /w "%~f0" "%~f0" 2^>nul') do (
  if not defined {key} set "{key}=%%A"
)
set "{key}=!{key}:~-1!"
if "!{key}!" equ "=" goto :{getKey}
for /f delims^=^ eol^= %%C in ("!{key}!") do if "!{valid}:%%C=!" neq "!{valid}!" (
  endlocal
  set "%~2=%%C"
  exit /b
)
goto :{getKey}
Here is the command to obfuscate the code:

Code: Select all

ObfuscateBatch /m batchMasterMind.bat
And below is the result.
I've posted the code so you can see how thorough the obfuscation is. But code page issues may create problems if you copy the code and paste it into your text editor.
So I have also attached a zip file that contains the correct binary image of the obfuscated code.

batchMasterMind_obfuscated.bat
batchMasterMind_obfuscated.zip
Updated 2019-08-11 to show result of version 1.2
(3.74 KiB) Downloaded 1664 times

Code: Select all

%<=%@%>=%e%r=%c%t=%h%r=%o%)=% %f=%o%f=%f%g=%f%l=%&%l=%(%b=%i%e=%f%f=% %r=%d%c=%e%)=%f%s=%i%e=%n%s=%e%a=%d%o=% %)=%@%t=%l%c=%o%n=%@%(=% %c=%g%i=%o%u=%t% =%o%s=% %u=%¡%n=%)%l=%&%b=%s%l=%e%u=%t%b=%l%r=%o%(=%c%i=%a%a=%l% =% %i=%d%b=%i%b=%s%l=%a%b=%b%)=%l%l=%e%e=%D%l=%e%a=%l%o=%a%o=%y%l=%e%b=%d%)=%E%(=%x%f=%p%c=%a%b=%n%l=%s%u=%i% =%o%)=%n%(=%&%s=%f%s=%o% =%r%l=% %u=%/% =%f%f=% %f=%"%(=%d%i=%e%s=%l%u=%i%)=%m%a=%s%i=%=%c=%:%)=%.%a=% %)=%t%a=%o%r=%k%(=%e%b=%n%c=%s%g=%=%r=%2%g=%"%r=% %u=%%%%t=%A%r=% %e=%i%r=%n%r=% %a=%(%e=%'%l=%c%u=%h%l=%c%s=%p%b=%'% =%)%g=% %(=%d%r=%o%o=% %e=%s%i=%e%(=%t%e=% %l=%"%r=%@%n=%c%b=%h%t=%c%r=%p%t=%@%l=%=%e=%c%s=%h%o=%c%)=%p%g=% %l=%%%A%a=%>% =%n%l=%u%s=%l%a=%"%c=%&%(=%c%b=%h%l=%c%i=%p%o=% %g=%7%f=%0%u=%8%c=%>%s=%n%)=%u%n=%l%o=%&%r=%s%)=%e%u=%t%i=% %b=%%(=%"%l=%@%l=%a%b=%r%b=%g%g=%s%o=%@%b=%=%b=%%*%c=%"%l=%
%u=%s%t=%e%i=%t%i=% %l=%"%a=%@%(=%l%s=%o%i=%@%o=%=%f=% !#$&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"%i=%"%s=%
%c=%s%a=%e%n=%t%s=% %i=%"%l=%@%f=%h%f=%i%g=%@%l=%=%e=%%i=%¡%l=%¢%e=%¤%s=%¥%a=%§%f=%¨% =%©%r=%ª%c=%«%e=%¬%l=%­%a=%®%r=%¯%e=%°%i=%±%(=%²%t=%³%e=%´%(=%µ%(=%¶%t=%·%e=%¸%t=%¹%t=%º%a=%»%t=%¼%o=%½%g=%¾%c=%¿%)=%À%a=%Á%b=%Â%b=%Ã%e=%Ä%g=%Å%l=%Æ%i=%Ç%b=%È%n=%É%o=%Ê%n=%Ë%r=%Ì%g=%Í% =%Î%g=%Ï%b=%Ð%s=%Ñ%u=%Ò%f=%Ó%s=%Ô%o=%Õ%a=%Ö%b=%×%l=%Ø%)=%Ù%)=%Ú%g=%Û%g=%Ü%l=%Ý%o=%Þ%)=%ß%)=%à%(=%á%)=%â%l=%ã%(=%ä%l=%å%o=%æ%l=%ç%i=%è%s=%é%l=%ê%l=%ë%a=%ì%s=%í%)=%î%o=%ï%l=%ð%o=%ñ%n=%ò%c=%ó%o=%ô%o=%õ%(=%ö%n=%÷%a=%ø% =%ù%n=%ú%f=%û%i=%ü%t=%ý%u=%þ%g=%ÿ%)=%£%l=%%)=%"% =%
%)=%(%s=%s%e=%e%i=%t%b=%l%c=%o% =%c%i=%a%(=%l% =% %s=%e%l=%n%t=%a%u=%b%e=%l%c=%e%b=%D%i=%e%g=%l%)=%a%f=%y%c=%e%i=%d%(=%E% =%x%f=%p%a=%a%f=%n%u=%s%l=%i%i=%o%e=%n%a=%&%b=%f%g=%o%e=%r%(=% %(=%/% =%l%s=% %u=%%%N%b=% %n=%i%r=%n%o=% %)=%(%(=%0%i=% %t=%1%r=% %s=%9%i=%3%l=%)%f=% %f=%d%l=%o%s=% %b=%s%t=%e%r=%t%l=% %s=%"%r=%!%b=%@%r=%h%l=%i%n=%@%l=%:%)=%~%l=%%%N%n=%,%i=%1%i=%!%s=%=%n=%!%g=%@%f=%l% =%o%c=%@%n=%:%n=%~%l=%%%N%n=%,%f=%1% =%!%c=%"%f=%)%r=%&%u=%c%n=%m%c=%d%o=% %u=%/%t=%c%r=% %r=%%u=%"%(=%"%l=%%~f0%b=%"%i=% %f=%%(=%"%f=%
%(=%%@chcp@%%g=%&%a=%e%e=%x% =%i%n=%t%l=% %l=%/%)=%b%g=%
:¡
::{:
:: BatchMasterMind.bat
::
:: Version History
:: 1.0  2014-12-31  - Original release
:: 2.0  2015-01-02  - Added menu for different rule variations
::                  - Added error message for invalid guess
::
:: Written by Dave Benham and Originally posted at
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=6153
::}
%Á%%æ%%ä%%é%%ð%%¡%%ð%%ç%%ç%
%ô%%æ%%õ%%í%%ð%%ä%%â%%í%%¡%%æ%%ï%%â%%ã%%í%%æ%%Å%%æ%%í%%â%%ú%%æ%%å%%Æ%%ù%%ñ%%â%%ï%%ô%%ê%%ð%%ï%

:{znvaZrah}
%ä%%í%%ô%
%æ%%ä%%é%%ð%%©%
%æ%%ä%%é%%ð%%©%%Î%%¡%%®%%¡%%Î%%â%%ô%%õ%%æ%%ó%%î%%ê%%ï%%å%%¡%%¡%%¡%%¡%%¡%%¡%%¡%%©%%ä%%ð%%å%%æ%%¡%%í%%æ%%ï%%è%%õ%%é%%¡%%µ%%­%%¡%%·%%¡%%ô%%ú%%î%%ã%%ð%%í%%ô%%­%%¡%%²%%±%%¡%%è%%ö%%æ%%ô%%ô%%æ%%ô%%ª%
%æ%%ä%%é%%ð%%©%%Ô%%¡%%®%%¡%%Ô%%ö%%ñ%%æ%%ó%%¡%%Î%%â%%ô%%õ%%æ%%ó%%î%%ê%%ï%%å%%¡%%©%%ä%%ð%%å%%æ%%¡%%í%%æ%%ï%%è%%õ%%é%%¡%%¶%%­%%¡%%¹%%¡%%ô%%ú%%î%%ã%%ð%%í%%ô%%­%%¡%%²%%³%%¡%%è%%ö%%æ%%ô%%ô%%æ%%ô%%ª%
%æ%%ä%%é%%ð%%©%%Ä%%¡%%®%%¡%%Ä%%ö%%ô%%õ%%ð%%î%
%æ%%ä%%é%%ð%%©%%Ò%%¡%%®%%¡%%Ò%%ö%%ê%%õ%
%æ%%ä%%é%%ð%%©%
%½%%ï%%ö%%í%%¡%%ô%%æ%%õ%%¡%%°%%ñ%%¡%%£%%¾%%¿%%¡%%£%
%ä%%â%%í%%í%%¡%%»%%ü%%õ%%ó%%è%%Ù%%ó%%í%%þ%%¡%%Î%%Ô%%Ä%%Ò%%¡%%ü%%ù%%ó%%í%%þ%
%ê%%ç%%¡%%°%%ê%%¡%%¢%%ü%%ù%%ó%%í%%þ%%¢%%¡%%æ%%ò%%ö%%¡%%Ò%%¡%%©%
%¡%%¡%%æ%%ä%%é%%ð%%¡%%Ò%
%¡%%¡%%æ%%ä%%é%%ð%%©%
%¡%%¡%%æ%%ù%%ê%%õ%%°%%ã%
%ª%%¡%%æ%%í%%ô%%æ%%¡%%ê%%ç%%¡%%°%%ê%%¡%%¢%%ü%%ù%%ó%%í%%þ%%¢%%¡%%æ%%ò%%ö%%¡%%Î%%¡%%©%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ç%%í%%û%%ð%%ã%%ú%%ç%%þ%%¾%%²%%³%%´%%µ%%¶%%·%%£%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%ì%%Õ%%é%%ó%%ç%%ç%%ó%%ç%%þ%%¾%%²%%±%%£%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ñ%%ã%%ò%%ó%%Ú%%ó%%â%%þ%%¾%%µ%%£%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ò%%é%%ä%%ç%%þ%%¾%%Ú%%£%
%ª%%¡%%æ%%í%%ô%%æ%%¡%%ê%%ç%%¡%%°%%ê%%¡%%¢%%ü%%ù%%ó%%í%%þ%%¢%%¡%%æ%%ò%%ö%%¡%%Ô%%¡%%©%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ç%%í%%û%%ð%%ã%%ú%%ç%%þ%%¾%%²%%³%%´%%µ%%¶%%·%%¸%%¹%%£%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%ì%%Õ%%é%%ó%%ç%%ç%%ó%%ç%%þ%%¾%%²%%³%%£%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ñ%%ã%%ò%%ó%%Ú%%ó%%â%%þ%%¾%%¶%%£%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ò%%é%%ä%%ç%%þ%%¾%%Ú%%£%
%ª%%¡%%æ%%í%%ô%%æ%%¡%%={ xrl rdh P }=%%¡%%©%
%¡%%¡%%ä%%â%%í%%í%%¡%%»%%ü%%ñ%%é%%ç%%è%%ã%%û%%þ%
%ª%

::%¡%%Ê%%ï%%ê%%õ%%ê%%â%%í%%ê%%û%%æ%
%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%è%%ñ%%ö%%Ä%%ã%%ç%%Ç%%í%%û%%ð%%ã%%ú%%þ%%¾%%Ù%%£%
%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%è%%ñ%%ö%%Ç%%í%%û%%Ç%%í%%û%%ð%%ã%%ú%%þ%%¾%%Ð%%£%
%ô%%æ%%õ%%¡%%£%%ü%%â%%ã%%Û%%ï%%è%%ñ%%ö%%Ç%%í%%û%%ð%%ã%%ú%%þ%%¾%%®%%£%
%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%ç%%ù%%Ç%%í%%û%%ð%%ã%%ú%%þ%%¾%%®%%£%
%ä%%â%%í%%í%%¡%%»%%ü%%ç%%è%%æ%%ú%%ó%%â%%þ%%¡%%ü%%ç%%í%%û%%ð%%ã%%ú%%ç%%þ%%¡%%ü%%ç%%í%%û%%ð%%ã%%ú%%Ñ%%â%%è%%þ%
%ô%%æ%%õ%%¡%%°%%â%%¡%%ü%%ñ%%ã%%ò%%ó%%Ç%%è%%ã%%ä%%þ%%¾%%ü%%ñ%%ã%%ò%%ó%%Ú%%ó%%â%%þ%%®%%²%
%ô%%æ%%õ%%¡%%£%%ü%%â%%ã%%Û%%ï%%è%%ñ%%ö%%þ%%¾%%£%
%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%ç%%ù%%þ%%¾%%£%
%ç%%ð%%ó%%¡%%°%%í%%¡%%%%Ï%%¡%%ê%%ï%%¡%%©%%²%%¡%%²%%¡%%{pbqrYra}%%ª%%¡%%å%%ð%%¡%%©%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%â%%ã%%Û%%ï%%è%%ñ%%ö%%þ%%¾%%¢%%ü%%â%%ã%%Û%%ï%%è%%ñ%%ö%%þ%%¢%%{abZngpuFlzoby}%%£%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%ç%%ù%%þ%%¾%%¢%%ü%%û%%ï%%ç%%ù%%þ%%¢%%¢%%ü%%û%%ï%%ç%%ù%%Ç%%í%%û%%ð%%ã%%ú%%þ%%¢%%£%
%ª%

::%¡%%Ô%%é%%ð%%ø%%¡%%É%%æ%%í%%ñ%
%ä%%í%%ô%
%æ%%ä%%é%%ð%%©%
%æ%%ä%%é%%ð%%¡%%Ú%%ð%%ö%%¡%%é%%â%%÷%%æ%%¡%%{znkThrffrf}%%¡%%è%%ö%%æ%%ô%%ô%%æ%%ô%%¡%%õ%%ð%%¡%%å%%æ%%å%%ö%%ä%%æ%%¡%%õ%%é%%æ%%¡%%{pbqrYra}%%¡%%ä%%é%%â%%ó%%â%%ä%%õ%%æ%%ó%%¡%%ä%%ð%%å%%æ%
%æ%%ä%%é%%ð%%¡%%ä%%ð%%ï%%ô%%ê%%ô%%õ%%ê%%ï%%è%%¡%%ð%%ç%%¡%%â%%ï%%ú%%¡%%ä%%ð%%î%%ã%%ê%%ï%%â%%õ%%ê%%ð%%ï%%¡%%ð%%ç%%¡%%õ%%é%%æ%%¡%%ç%%ð%%í%%í%%ð%%ø%%ê%%ï%%è%%¡%%ô%%ú%%î%%ã%%ð%%í%%ô%%»%
%æ%%ä%%é%%ð%%©%
%æ%%ä%%é%%ð%%¡%%¡%%¡%%¢%%ü%%ç%%í%%û%%ð%%ã%%ú%%ç%%þ%%¢%
%æ%%ä%%é%%ð%%©%
%ê%%ç%%¡%%°%%ê%%¡%%¢%%ü%%ò%%é%%ä%%ç%%þ%%¢%%¡%%æ%%ò%%ö%%¡%%Ú%%¡%%©%
%¡%%¡%%æ%%ä%%é%%ð%%¡%%Å%%ö%%ñ%%í%%ê%%ä%%â%%õ%%æ%%¡%%ô%%ú%%î%%ã%%ð%%í%%ô%%¡%%â%%ó%%æ%%¡%%â%%í%%í%%ð%%ø%%æ%%å%%¡%%ê%%ï%%¡%%õ%%é%%æ%%¡%%ä%%ð%%å%%æ%%¯%
%ª%%¡%%æ%%í%%ô%%æ%%¡%%©%
%¡%%¡%%æ%%ä%%é%%ð%%¡%%Å%%ö%%ñ%%í%%ê%%ä%%â%%õ%%æ%%¡%%ô%%ú%%î%%ã%%ð%%í%%ô%%¡%%â%%ó%%æ%%¡%%Ï%%Ð%%Õ%%¡%%â%%í%%í%%ð%%ø%%æ%%å%%¡%%ê%%ï%%¡%%õ%%é%%æ%%¡%%ä%%ð%%å%%æ%%¯%
%ª%
%æ%%ä%%é%%ð%%©%
%æ%%ä%%é%%ð%%¡%%Õ%%é%%æ%%¡%%ï%%ö%%î%%ã%%æ%%ó%%¡%%ð%%ç%%¡%%¢%%ü%%û%%ï%%è%%ñ%%ö%%Ä%%ã%%ç%%Ç%%í%%û%%ð%%ã%%ú%%þ%%¢%%¡%%ä%%é%%â%%ó%%â%%ä%%õ%%æ%%ó%%ô%%¡%%õ%%æ%%í%%í%%ô%%¡%%ú%%ð%%ö%%¡%%é%%ð%%ø%%¡%%î%%â%%ï%%ú%%¡%%ô%%ú%%î%%ã%%ð%%í%%ô%
%æ%%ä%%é%%ð%%¡%%î%%â%%õ%%ä%%é%%¡%%â%%ï%%å%%¡%%â%%ó%%æ%%¡%%ê%%ï%%¡%%õ%%é%%æ%%¡%%ä%%ð%%ó%%ó%%æ%%ä%%õ%%¡%%ñ%%ð%%ô%%ê%%õ%%ê%%ð%%ï%%¯%
%æ%%ä%%é%%ð%%©%
%æ%%ä%%é%%ð%%¡%%Õ%%é%%æ%%¡%%ï%%ö%%î%%ã%%æ%%ó%%¡%%ð%%ç%%¡%%¢%%ü%%û%%ï%%è%%ñ%%ö%%Ç%%í%%û%%Ç%%í%%û%%ð%%ã%%ú%%þ%%¢%%¡%%ä%%é%%â%%ó%%â%%ä%%õ%%æ%%ó%%ô%%¡%%õ%%æ%%í%%í%%ô%%¡%%ú%%ð%%ö%%¡%%é%%ð%%ø%%¡%%î%%â%%ï%%ú%%¡%%ô%%ú%%î%%ã%%ð%%í%%ô%
%æ%%ä%%é%%ð%%¡%%î%%â%%õ%%ä%%é%%¡%%ã%%ö%%õ%%¡%%â%%ó%%æ%%¡%%ê%%ï%%¡%%õ%%é%%æ%%¡%%ø%%ó%%ð%%ï%%è%%¡%%ñ%%ð%%ô%%ê%%õ%%ê%%ð%%ï%%¯%
%æ%%ä%%é%%ð%%©%
%ñ%%â%%ö%%ô%%æ%

:{cynl}

::%¡%%È%%æ%%õ%%Ä%%ð%%å%%æ%
%ô%%æ%%õ%%¡%%£%%ü%%ú%%÷%%ç%%è%%þ%%¾%%¢%%ü%%ç%%í%%û%%ð%%ã%%ú%%ç%%þ%%¢%%£%
%ô%%æ%%õ%%¡%%£%%ü%%ú%%ó%%â%%þ%%¾%%{flzobyPag}%%£%
%ô%%æ%%õ%%¡%%£%%ü%%ñ%%ã%%ò%%ó%%þ%%¾%%£%
%ç%%ð%%ó%%¡%%°%%í%%¡%%%%Ï%%¡%%ê%%ï%%¡%%©%%±%%¡%%²%%¡%%{pbqrFgbc}%%ª%%¡%%å%%ð%%¡%%©%
%¡%%¡%%ô%%æ%%õ%%¡%%°%%â%%¡%%£%%ï%%¾%%¢%%ó%%â%%ï%%å%%ð%%î%%¢%%%%ü%%ú%%ó%%â%%þ%%£%
%¡%%¡%%ç%%ð%%ó%%¡%%%%Â%%¡%%ê%%ï%%¡%%©%%¢%%ï%%¢%%ª%%¡%%å%%ð%%¡%%©%
%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ñ%%ã%%ò%%ó%%þ%%¾%%¢%%ü%%ñ%%ã%%ò%%ó%%þ%%¢%%¢%%ü%%ú%%÷%%ç%%è%%þ%%»%%ÿ%%%%Â%%­%%²%%¢%%£%
%¡%%¡%%¡%%¡%%ê%%ç%%¡%%°%%ê%%¡%%¢%%ü%%ò%%é%%ä%%ç%%þ%%¢%%¡%%æ%%ò%%ö%%¡%%Ï%%¡%%©%
%¡%%¡%%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%°%%â%%¡%%£%%ï%%¬%%¾%%²%%­%%¡%%ü%%ú%%ó%%â%%þ%%®%%¾%%²%%£%
%¡%%¡%%¡%%¡%%¡%%¡%%ç%%ð%%ó%%¡%%%%Ã%%¡%%ê%%ï%%¡%%©%%¢%%ï%%¢%%ª%%¡%%å%%ð%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ú%%÷%%ç%%è%%þ%%¾%%¢%%ü%%ú%%÷%%ç%%è%%þ%%»%%ÿ%%±%%­%%%%Â%%¢%%¢%%ü%%ú%%÷%%ç%%è%%þ%%»%%ÿ%%%%Ã%%¢%%£%
%¡%%¡%%¡%%¡%%ª%
%¡%%¡%%ª%
%ª%

::%¡%%Ä%%í%%æ%%â%%ó%%Õ%%ö%%ó%%ï%%ô%
%ç%%ð%%ó%%¡%%°%%í%%¡%%%%Ï%%¡%%ê%%ï%%¡%%©%%²%%¡%%²%%¡%%{znkThrffrf}%%ª%%¡%%å%%ð%%¡%%ê%%ç%%¡%%%%Ï%%¡%%í%%ô%%ô%%¡%%²%%±%%¡%%©%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%è%%é%%æ%%â%%þ%%Ü%%%%Ï%%Þ%%¾%%¡%%¡%%%%Ï%%£%
%ª%%¡%%æ%%í%%ô%%æ%%¡%%©%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%è%%é%%æ%%â%%þ%%Ü%%%%Ï%%Þ%%¾%%¡%%%%Ï%%£%
%ª%

::%¡%%Õ%%ö%%ó%%ï%%¡%%Í%%ð%%ð%%ñ%
%ç%%ð%%ó%%¡%%°%%í%%¡%%%%Õ%%¡%%ê%%ï%%¡%%©%%{znkThrffrf}%%¡%%®%%²%%¡%%²%%ª%%¡%%å%%ð%%¡%%©%

%¡%%¡%%ä%%â%%í%%í%%¡%%»%%ü%%ç%%ö%%ã%%ë%%Ð%%ã%%ï%%æ%%ò%%þ%%¡%%ü%%û%%ï%%ç%%ù%%þ%
%¡%%¡%%ä%%â%%í%%í%%¡%%»%%ü%%õ%%ó%%è%%Õ%%é%%ó%%ç%%ç%%þ%

%¡%%¡%%={ Pbzchgr Fpber }=%
%¡%%¡%%ç%%ð%%ó%%¡%%°%%í%%¡%%%%Â%%¡%%ê%%ï%%¡%%©%%±%%¡%%²%%¡%%{pbqrFgbc}%%ª%%¡%%å%%ð%%¡%%©%
%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%õ%%é%%ó%%ç%%ç%%þ%%Ü%%%%Â%%Þ%%¾%%¢%%ü%%õ%%é%%ó%%ç%%ç%%þ%%»%%ÿ%%%%Â%%­%%²%%¢%%£%
%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ñ%%ã%%ò%%ó%%þ%%Ü%%%%Â%%Þ%%¾%%¢%%ü%%ñ%%ã%%ò%%ó%%þ%%»%%ÿ%%%%Â%%­%%²%%¢%%£%
%¡%%¡%%ª%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%è%%ñ%%ö%%Ä%%ã%%ç%%þ%%¾%%£%
%¡%%¡%%ç%%ð%%ó%%¡%%°%%í%%¡%%%%Â%%¡%%ê%%ï%%¡%%©%%±%%¡%%²%%¡%%{pbqrFgbc}%%ª%%¡%%å%%ð%%¡%%ê%%ç%%¡%%¢%%ü%%õ%%é%%ó%%ç%%ç%%þ%%Ü%%%%Â%%Þ%%¢%%¡%%æ%%ò%%ö%%¡%%¢%%ü%%ñ%%ã%%ò%%ó%%þ%%Ü%%%%Â%%Þ%%¢%%¡%%©%
%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%è%%ñ%%ö%%Ä%%ã%%ç%%þ%%¾%%¢%%ü%%û%%ï%%è%%ñ%%ö%%Ä%%ã%%ç%%þ%%¢%%¢%%ü%%û%%ï%%è%%ñ%%ö%%Ä%%ã%%ç%%Ç%%í%%û%%ð%%ã%%ú%%þ%%¢%%£%
%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%õ%%é%%ó%%ç%%ç%%þ%%Ü%%%%Â%%Þ%%¾%%£%
%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ñ%%ã%%ò%%ó%%þ%%Ü%%%%Â%%Þ%%¾%%£%
%¡%%¡%%ª%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%è%%ñ%%ö%%Ç%%í%%û%%þ%%¾%%£%
%¡%%¡%%ç%%ð%%ó%%¡%%°%%í%%¡%%%%Â%%¡%%ê%%ï%%¡%%©%%±%%¡%%²%%¡%%{pbqrFgbc}%%ª%%¡%%å%%ð%%¡%%ç%%ð%%ó%%¡%%°%%í%%¡%%%%Ã%%¡%%ê%%ï%%¡%%©%%±%%¡%%²%%¡%%{pbqrFgbc}%%ª%%¡%%å%%ð%%¡%%ê%%ç%%¡%%å%%æ%%ç%%ê%%ï%%æ%%å%%¡%%ü%%õ%%é%%ó%%ç%%ç%%þ%%Ü%%%%Â%%Þ%%¡%%ê%%ç%%¡%%¢%%ü%%õ%%é%%ó%%ç%%ç%%þ%%Ü%%%%Â%%Þ%%¢%%¡%%æ%%ò%%ö%%¡%%¢%%ü%%ñ%%ã%%ò%%ó%%þ%%Ü%%%%Ã%%Þ%%¢%%¡%%©%
%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%è%%ñ%%ö%%Ç%%í%%û%%þ%%¾%%¢%%ü%%û%%ï%%è%%ñ%%ö%%Ç%%í%%û%%þ%%¢%%¢%%ü%%û%%ï%%è%%ñ%%ö%%Ç%%í%%û%%Ç%%í%%û%%ð%%ã%%ú%%þ%%¢%%£%
%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%õ%%é%%ó%%ç%%ç%%þ%%Ü%%%%Â%%Þ%%¾%%£%
%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ñ%%ã%%ò%%ó%%þ%%Ü%%%%Ã%%Þ%%¾%%£%
%¡%%¡%%ª%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ç%%ñ%%ã%%æ%%ó%%þ%%¾%%¢%%ü%%û%%ï%%è%%ñ%%ö%%Ä%%ã%%ç%%þ%%¢%%¢%%ü%%û%%ï%%è%%ñ%%ö%%Ç%%í%%û%%þ%%¢%%¢%%ü%%â%%ã%%Û%%ï%%è%%ñ%%ö%%þ%%¢%%£%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ç%%ñ%%ã%%æ%%ó%%þ%%¾%%¢%%ü%%ç%%ñ%%ã%%æ%%ó%%þ%%»%%ÿ%%±%%­%%{pbqrYra}%%¢%%£%

%¡%%¡%%={ Qrsvar Ghea }=%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%ü%%è%%é%%æ%%â%%þ%%Ü%%%%Õ%%Þ%%¾%%¢%%ü%%è%%é%%æ%%â%%þ%%Ü%%%%Õ%%Þ%%¢%%¡%%¡%%¡%%¢%%ü%%õ%%é%%ó%%ç%%ç%%þ%%¢%%¡%%¡%%¢%%ü%%ç%%ñ%%ã%%æ%%ó%%þ%%¢%%£%

%¡%%¡%%={ Purpx sbe jvaare }=%
%¡%%¡%%ê%%ç%%¡%%¢%%ü%%õ%%é%%ó%%ç%%ç%%þ%%¢%%¡%%æ%%ò%%ö%%¡%%¢%%ü%%ñ%%ã%%ò%%ó%%þ%%¢%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%ó%%â%%ò%%Õ%%ï%%û%%ó%%þ%
%ª%


:{raqTnzr}
%ä%%â%%í%%í%%¡%%»%%ü%%ç%%ö%%ã%%ë%%Ð%%ã%%ï%%æ%%ò%%þ%%¡%%ü%%ñ%%ã%%ò%%ó%%þ%
%ê%%ç%%¡%%¢%%ü%%õ%%é%%ó%%ç%%ç%%þ%%¢%%¡%%æ%%ò%%ö%%¡%%¢%%ü%%ñ%%ã%%ò%%ó%%þ%%¢%%¡%%©%%æ%%ä%%é%%ð%%¡%%Ú%%ð%%ö%%¡%%Ø%%Ê%%Ï%%ß%%ß%%¢%%ª%%¡%%æ%%í%%ô%%æ%%¡%%©%%æ%%ä%%é%%ð%%¡%%Ú%%ð%%ö%%¡%%Í%%Ð%%Ô%%Æ%%ß%%ß%%¢%%ª%
%æ%%ä%%é%%ð%%©%
%½%%ï%%ö%%í%%¡%%ô%%æ%%õ%%¡%%°%%ñ%%¡%%£%%¾%%Ñ%%í%%â%%ú%%¡%%â%%è%%â%%ê%%ï%%¡%%Ü%%Ú%%Ï%%Þ%%À%%¡%%£%
%ä%%â%%í%%í%%¡%%»%%ü%%õ%%ó%%è%%Ù%%ó%%í%%þ%%¡%%Ú%%Ï%%¡%%ü%%ù%%ó%%í%%þ%
%ê%%ç%%¡%%°%%ê%%¡%%¢%%ü%%ù%%ó%%í%%þ%%¢%%¡%%æ%%ò%%ö%%¡%%Ú%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%ä%%ú%%ï%%í%%þ%
%è%%ð%%õ%%ð%%¡%%»%%ü%%û%%ï%%÷%%â%%Û%%ó%%â%%é%%þ%


:{onqThrff}
%æ%%ä%%é%%ð%%¡%%Ê%%ï%%÷%%â%%í%%ê%%å%%¡%%è%%ö%%æ%%ô%%ô%%¡%%®%%¡%%Î%%ö%%ô%%õ%%¡%%é%%â%%÷%%æ%%¡%%í%%æ%%ï%%è%%õ%%é%%¡%%{pbqrYra}%%¡%%ø%%ê%%õ%%é%%¡%%÷%%â%%í%%ê%%å%%¡%%ô%%ú%%î%%ã%%ð%%í%%ô%%¡%%ð%%ï%%í%%ú%

:{trgThrff}
%ô%%æ%%õ%%¡%%£%%ü%%õ%%é%%ó%%ç%%ç%%þ%%¾%%£%
%ô%%æ%%õ%%¡%%°%%ñ%%¡%%£%%ü%%õ%%é%%ó%%ç%%ç%%þ%%¾%%È%%ö%%æ%%ô%%ô%%¡%%£%
%ê%%ç%%¡%%ï%%ð%%õ%%¡%%å%%æ%%ç%%ê%%ï%%æ%%å%%¡%%ü%%õ%%é%%ó%%ç%%ç%%þ%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%ð%%ï%%ò%%Õ%%é%%ó%%ç%%ç%%þ%
%ç%%ð%%ó%%¡%%°%%ç%%¡%%£%%å%%æ%%í%%ê%%î%%ô%%¾%%{flzobyf}%%¡%%æ%%ð%%í%%¾%%{flzobyf}:~0,1%%£%%¡%%%%Â%%¡%%ê%%ï%%¡%%©%%£%%{thrff}%%£%%ª%%¡%%å%%ð%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%ð%%ï%%ò%%Õ%%é%%ó%%ç%%ç%%þ%
%ê%%ç%%¡%%£%%¢%%ü%%õ%%é%%ó%%ç%%ç%%þ%%»%%ÿ%%{pbqrYra}%%¢%%£%%¡%%ï%%æ%%ò%%¡%%£%%£%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%ð%%ï%%ò%%Õ%%é%%ó%%ç%%ç%%þ%
%ê%%ç%%¡%%£%%¢%%ü%%õ%%é%%ó%%ç%%ç%%þ%%»%%ÿ%%{pbqrFgbc}%%¢%%£%%¡%%æ%%ò%%ö%%¡%%£%%£%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%ð%%ï%%ò%%Õ%%é%%ó%%ç%%ç%%þ%
%æ%%ù%%ê%%õ%%¡%%°%%ã%


:{fubjObneq} %¡%%õ%%â%%ó%%è%%æ%%õ%
%ä%%í%%ô%
%æ%%ä%%é%%ð%%©%
%æ%%ä%%é%%ð%%¡%%¡%%¡%%¡%%¡%%¡%%¡%%¢%%1%¢%%¡%%¡%%Ü%%¢%%ü%%ç%%í%%û%%ð%%ã%%ú%%ç%%þ%%¢%%Þ%
%æ%%ä%%é%%ð%%©%
%ç%%ð%%ó%%¡%%°%%í%%¡%%%%Ï%%¡%%ê%%ï%%¡%%©%%{znkThrffrf}%%¡%%®%%²%%¡%%²%%ª%%¡%%å%%ð%%¡%%æ%%ä%%é%%ð%%¡%%¢%%ü%%è%%é%%æ%%â%%þ%%Ü%%%%Ï%%Þ%%¢%
%æ%%ä%%é%%ð%%©%
%æ%%ù%%ê%%õ%%¡%%°%%ã%


:{fgeyra} %¡%%Ô%%õ%%ó%%×%%â%%ó%%¡%%¡%%Ó%%õ%%ï%%×%%â%%ó%
%ô%%æ%%õ%%í%%ð%%ä%%â%%í%%¡%%æ%%ï%%â%%ã%%í%%æ%%Å%%æ%%í%%â%%ú%%æ%%å%%Æ%%ù%%ñ%%â%%ï%%ô%%ê%%ð%%ï%
%ô%%æ%%õ%%¡%%£%%ô%%¾%%¢%%~1%¢%%¤%%£%
%ô%%æ%%õ%%¡%%£%%ü%%ú%%ó%%â%%þ%%¾%%±%%£%
%ç%%ð%%ó%%¡%%%%Ñ%%¡%%ê%%ï%%¡%%©%%µ%%±%%º%%·%%¡%%³%%±%%µ%%¹%%¡%%²%%±%%³%%µ%%¡%%¶%%²%%³%%¡%%³%%¶%%·%%¡%%²%%³%%¹%%¡%%·%%µ%%¡%%´%%³%%¡%%²%%·%%¡%%¹%%¡%%µ%%¡%%³%%¡%%²%%ª%%¡%%å%%ð%%¡%%©%
%¡%%¡%%ê%%ç%%¡%%£%%¢%%ô%%»%%ÿ%%%%Ñ%%­%%²%%¢%%£%%¡%%Ï%%Æ%%Ò%%¡%%£%%£%%¡%%©%
%¡%%¡%%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%°%%â%%¡%%£%%ü%%ú%%ó%%â%%þ%%¬%%¾%%%%Ñ%%£%
%¡%%¡%%¡%%¡%%¡%%¡%%ô%%æ%%õ%%¡%%£%%ô%%¾%%¢%%ô%%»%%ÿ%%%%Ñ%%¢%%£%
%¡%%¡%%ª%
%ª%
%æ%%ï%%å%%í%%ð%%ä%%â%%í%%¡%%§%%¡%%ô%%æ%%õ%%¡%%£%%~2%¾%%{yra}%%£%
%æ%%ù%%ê%%õ%%¡%%°%%ã%


:{phfgbz}
%ä%%í%%ô%
%æ%%ä%%é%%ð%%©%

:{trgFlzobyf}
%ô%%æ%%õ%%¡%%£%%ü%%ç%%í%%û%%ð%%ã%%ú%%ç%%þ%%¾%%£%
%ô%%æ%%õ%%¡%%°%%ñ%%¡%%£%%ü%%ç%%í%%û%%ð%%ã%%ú%%ç%%þ%%¾%%Ô%%ú%%î%%ã%%ð%%í%%ô%%¡%%¾%%¡%%£%
%ê%%ç%%¡%%ï%%ð%%õ%%¡%%å%%æ%%ç%%ê%%ï%%æ%%å%%¡%%ü%%ç%%í%%û%%ð%%ã%%ú%%ç%%þ%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%õ%%ó%%è%%Ç%%í%%û%%ð%%ã%%ú%%ç%%þ%

:{trgPbqrYra}
%ô%%æ%%õ%%¡%%£%%ü%%ñ%%ã%%ò%%ó%%Ú%%ó%%â%%þ%%¾%%£%
%ô%%æ%%õ%%¡%%°%%ñ%%¡%%£%%ü%%ñ%%ã%%ò%%ó%%Ú%%ó%%â%%þ%%¾%%Ä%%ð%%å%%æ%%¡%%í%%æ%%ï%%è%%õ%%é%%¡%%¾%%¡%%£%
%³%%¿%%ï%%ö%%í%%¡%%ô%%æ%%õ%%¡%%°%%â%%¡%%ü%%ñ%%ã%%ò%%ó%%Ú%%ó%%â%%þ%%¾%%ü%%ñ%%ã%%ò%%ó%%Ú%%ó%%â%%þ%%¡%%ý%%ý%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%õ%%ó%%è%%Ñ%%ã%%ò%%ó%%Ú%%ó%%â%%þ%
%ê%%ç%%¡%%{pbqrYra}%%¡%%í%%ô%%ô%%¡%%²%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%õ%%ó%%è%%Ñ%%ã%%ò%%ó%%Ú%%ó%%â%%þ%

%½%%ï%%ö%%í%%¡%%ô%%æ%%õ%%¡%%°%%ñ%%¡%%£%%¾%%Â%%í%%í%%ð%%ø%%¡%%å%%ö%%ñ%%í%%ê%%ä%%â%%õ%%æ%%¡%%ô%%ú%%î%%ã%%ð%%í%%ô%%¡%%ê%%ï%%¡%%ä%%ð%%å%%æ%%À%%¡%%Ü%%Ú%%Ï%%Þ%%¡%%£%
%ä%%â%%í%%í%%¡%%»%%ü%%õ%%ó%%è%%Ù%%ó%%í%%þ%%¡%%Ú%%Ï%%¡%%ü%%ò%%é%%ä%%ç%%þ%
%æ%%ä%%é%%ð%%¡%%¢%%ü%%ò%%é%%ä%%ç%%þ%%¢%

:{trgZnkThrffrf}
%ô%%æ%%õ%%¡%%£%%ü%%û%%ï%%ì%%Õ%%é%%ó%%ç%%ç%%ó%%ç%%þ%%¾%%£%
%ô%%æ%%õ%%¡%%°%%ñ%%¡%%£%%ü%%û%%ï%%ì%%Õ%%é%%ó%%ç%%ç%%ó%%ç%%þ%%¾%%Î%%â%%ù%%¡%%è%%ö%%æ%%ô%%ô%%æ%%ô%%¡%%¾%%¡%%£%
%³%%¿%%ï%%ö%%í%%¡%%ô%%æ%%õ%%¡%%°%%â%%¡%%ü%%û%%ï%%ì%%Õ%%é%%ó%%ç%%ç%%ó%%ç%%þ%%¾%%ü%%û%%ï%%ì%%Õ%%é%%ó%%ç%%ç%%ó%%ç%%þ%%¡%%ý%%ý%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%õ%%ó%%è%%Û%%ï%%ì%%Õ%%é%%ó%%ç%%ç%%ó%%ç%%þ%
%ê%%ç%%¡%%{znkThrffrf}%%¡%%í%%ô%%ô%%¡%%²%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%õ%%ó%%è%%Û%%ï%%ì%%Õ%%é%%ó%%ç%%ç%%ó%%ç%%þ%
%æ%%ù%%ê%%õ%%¡%%°%%ã%


:{trgXrl} %¡%%÷%%â%%í%%ê%%å%%Í%%ê%%ô%%õ%%¡%%¡%%ó%%õ%%ï%%×%%â%%ó%
%ô%%æ%%õ%%í%%ð%%ä%%â%%í%
%ô%%æ%%õ%%¡%%£%%ü%%ê%%ï%%ú%%÷%%ò%%þ%%¾%%~1%£%
%ô%%æ%%õ%%¡%%£%%ü%%ù%%ó%%í%%þ%%¾%%£%
%ç%%ð%%ó%%¡%%°%%ç%%¡%%£%%å%%æ%%í%%ê%%î%%ô%%¾%%£%%¡%%%%Â%%¡%%ê%%ï%%¡%%©%%¨%%ù%%ä%%ð%%ñ%%ú%%¡%%°%%ø%%¡%%£%%~f0%£%%¡%%£%%~f0%£%%¡%%³%%ß%%¿%%ï%%ö%%í%%¨%%ª%%¡%%å%%ð%%¡%%©%
%¡%%¡%%ê%%ç%%¡%%ï%%ð%%õ%%¡%%å%%æ%%ç%%ê%%ï%%æ%%å%%¡%%ü%%ù%%ó%%í%%þ%%¡%%ô%%æ%%õ%%¡%%£%%ü%%ù%%ó%%í%%þ%%¾%%%%Â%%£%
%ª%
%ô%%æ%%õ%%¡%%£%%ü%%ù%%ó%%í%%þ%%¾%%¢%%ü%%ù%%ó%%í%%þ%%»%%ÿ%%®%%²%%¢%%£%
%ê%%ç%%¡%%£%%¢%%ü%%ù%%ó%%í%%þ%%¢%%£%%¡%%æ%%ò%%ö%%¡%%£%%¾%%£%%¡%%è%%ð%%õ%%ð%%¡%%»%%ü%%õ%%ó%%è%%Ù%%ó%%í%%þ%
%ç%%ð%%ó%%¡%%°%%ç%%¡%%å%%æ%%í%%ê%%î%%ô%%ß%%¾%%ß%%¡%%æ%%ð%%í%%ß%%¾%%¡%%%%Ä%%¡%%ê%%ï%%¡%%©%%£%%¢%%ü%%ù%%ó%%í%%þ%%¢%%£%%ª%%¡%%å%%ð%%¡%%ê%%ç%%¡%%£%%¢%%ü%%ê%%ï%%ú%%÷%%ò%%þ%%»%%%%Ä%%¾%%¢%%£%%¡%%ï%%æ%%ò%%¡%%£%%¢%%ü%%ê%%ï%%ú%%÷%%ò%%þ%%¢%%£%%¡%%©%
%¡%%¡%%æ%%ï%%å%%í%%ð%%ä%%â%%í%
%¡%%¡%%ô%%æ%%õ%%¡%%£%%~2%¾%%%%Ä%%£%
%¡%%¡%%æ%%ù%%ê%%õ%%¡%%°%%ã%
%ª%
%è%%ð%%õ%%ð%%¡%%»%%ü%%õ%%ó%%è%%Ù%%ó%%í%%þ%
As additional tests, I've also obfuscated batchObfuscate.bat and SNAKE.BAT (not shown).
Both worked flawlessly, and there wasn't any noticeable degradation of SNAKE.BAT performance 8) :!:

Have fun with this :D


Dave Benham

PaperTronics
Posts: 118
Joined: 02 Apr 2017 06:11

Re: Best way to obfuscate a Batch File?

#22 Post by PaperTronics » 07 Aug 2017 06:34

@dbenham - Your code impresses me as much as your flute music does! It works flawlessly on every program that I test, but unfortunately, the labels aren't obfuscated. Probably because I was too indolent to surround them with braces. Though my friend is okay with the labels being readable, as long as the password is safe 'n secure, my friend is going be more than happy for it.

@penpen - Now I get it! Your sketched method is clear to me but since dbenham's code is working as desired, I don't need to implement your code.


@aGerman - My friend isn't okay with the code being visible with a hex editor since many of his colleagues are super-computer nerds and he suspects them to have a hex editor which could reveal his password.


PaperTronics

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Best way to obfuscate a Batch File?

#23 Post by dbenham » 07 Aug 2017 06:46

PaperTronics wrote:My friend isn't okay with the code being visible with a hex editor since many of his colleagues are super-computer nerds and he suspects them to have a hex editor which could reveal his password.

This statement concerns me. Any moderate computer nerd could discover the password from any batch file you create, regardless what obfuscation you throw at it.

Dave Benham

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Best way to obfuscate a Batch File?

#24 Post by ShadowThief » 07 Aug 2017 13:52

It's starting to sound like you should consider an alternative language for this project, unfortunately. Something that's meant to be compiled (although not Java; decompiling jar and class files is trivial).

PaperTronics
Posts: 118
Joined: 02 Apr 2017 06:11

Re: Best way to obfuscate a Batch File?

#25 Post by PaperTronics » 08 Aug 2017 10:56

@dbenham - I just wrote "super-computer nerds" cuz' my friend was spying on this topic yesterday and he calls everyone who knows basically anything about computers, "super-computer nerds". These "nerds" don't know that much about Batch programming as they have knowledge of C++ and other languages, but they can dig out the batch code to find the password. If you still don't understand, I don't blame you.. but that's how things go in around in my country! :wink:

@ShadowThief - I can't do the login project in another language because as I described above, my friends colleagues are experienced with C++, Python and VBS. C++ and Python are the only languages I know besides Batch, and since Python can't be compiled, C++ is the option. But, I don't know if C++ can be converted to EXE or not. If it can, then I'll be willing to do it in C++.



PaperTronics

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Best way to obfuscate a Batch File?

#26 Post by penpen » 08 Aug 2017 15:28

PaperTronics wrote:But, I don't know if C++ can be converted to EXE or not.
If there was ever something that can be "converted" to exe (on any platform), then it is C++ source code.

You could use for example "Visual Studio Community 2017" to create C++-Projects and compile (and link) it.
As far as i know "Visual Studio Community 2017" is free for private use; it can be found here:
https://www.visualstudio.com.


penpen

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Best way to obfuscate a Batch File?

#27 Post by ShadowThief » 08 Aug 2017 17:07

Python can absolutely be compiled, and like penpen said earlier, C++ is meant to be compiled.

PaperTronics
Posts: 118
Joined: 02 Apr 2017 06:11

Re: Best way to obfuscate a Batch File?

#28 Post by PaperTronics » 09 Aug 2017 05:32

@ShadowThief - I took yours and penpen's advice and created the login project in C++, compiled it and presented it to my friend. He was fairly happy as the code cannot be viewed and it does the login thing perfectly. Thanks guys, for solving mine and my friend's problem and educating me with some obfuscating knowledge too along the way!

@dbenham - I like your obfuscating batch file so much, that I may even use it on my new game! Do you mind if I post about it on my website?


Thanks again guys!
PaperTronics

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Best way to obfuscate a Batch File?

#29 Post by penpen » 09 Aug 2017 12:43

Just one last thing to say, all that is said about handling login and password data in batch also should be taken care off in C++ (and any other language):
So you shouldn't store login and passwords in "clear text" because you could also easily resore that using for example a hex editor, Hex-Rays/IDA, snowman or ollydebug.


penpen

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Best way to obfuscate a Batch File?

#30 Post by ShadowThief » 09 Aug 2017 16:46

I know I post this a lot in topics like these, but salt and hash your passwords and then store the resulting salts and hashes. https://www.youtube.com/watch?v=8ZtInClXe1Q

Post Reply