Discussion:
OBFUSCATE.CMD
(too old to reply)
f***@gmail.com
12 years ago
Permalink
:: BEGIN SCRIPT :::::::::::::::::::::::::::::::::::::::::::::::::::::
:: From the desk of Frank P. Westlake, 2013-01-02
:: This item is being sold as a novelty only.
:? OBFUSCATE.CMD
:? Obfuscates or deobfuscates standard input to standard output.
:? Version 2013-01-02
:? USAGE
:? obsufcate [/E | /D] [<key>]
:?
:? /E Encode input to output (default).
:? /D Decode input to output.
:? key An optional encoding key to replace the default.
:?
:? The default behavior is to encode input to output
using the internal
:? key. The internal key may be replaced by one on the
command line so
:? that it may remain secret and the character order
changable.
:?
:? The built-in key contains only the printable ASCII
characters but other
:? single byte characters may be added to it.
:?
:? EXAMPLES
:? TYPE bogus.cmd | obfuscate /D > good.cmd & good.cmd & DEL good.cmd
:? TYPE sample | obfuscate | obfuscate /d
@Echo OFF
SetLocal EnableExtensions DisableDelayedExpansion
:: DEFAULTS
Set "which=encode"
Set "TAB= "
Set "SP= "
For /F "delims=%SP%" %%a in ("1%TAB%") Do If "%%~a" EQU "1" (
(Echo %~nx0: The script's variable 'TAB' must be defined as a tab character.
Set /P "=LINE "<NUL:
FindStr /n /i /c:"TAB=" "%~f0"|FindStr /v "FindStr")>&2
Goto :EOF
)
Set "key=%tab%%sp%01234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm~`!@#$%%^&*()-_=+[{]}\|;:',<.>/?""
:args
:: ARGUMENTS
Set "$=%~1"
If DEFINED $ (
If "%$%" EQU "/?" (
SetLocal EnableDelayedExpansion
For /F "delims=" %%a in ('FindStr ":\?" %~f0') Do (
Set "$=%%a"
Echo;!$:~3!
)
EndLocal
Goto :EOF
)
If /I "%$%" EQU "/D" (
Set "which=decode"
) Else If /I "%$%" EQU "/E" (
Set "which=encode"
) Else (
Set "key=%~1"
)
SHIFT
Goto :args
)
:main
Set "hex=0123456789ABCDEF"
For /F "tokens=1 delims==" %%a in ('Set "$" 2^>NUL:') Do Set "%%a="
Set "$=%key%"
For /F "delims=:" %%a in (
'(SET $^& Echo.NEXT LINE^)^|FindStr /O "NEXT LINE"'
) Do Set /A "keyLength=%%a-4, keyLen=keyLength-1"
Set "forParams=delims^=^ eol^="
For /F %forParams% %%a in ('FindStr "^"') Do (
Set "line=%%a"
Call :%which%
)
Goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:encode
SetLocal EnableDelayedExpansion
Set "codedLine="
:encode.loop
Set "c=!line:~0,1!"
Set "line=!line:~1!"
For /L %%i in (0 1 %keyLength%) Do (
If "!c!" EQU "!key:~%%i,1!" (
Set /A "hi=(%%i>>4)&0xF, lo=%%i&0xF"
For /F "tokens=1,2" %%j in ("!hi! !lo!") Do (
Set "codedLine=!codedLine!!hex:~%%j,1!!hex:~%%k,1!"
)
Goto :break
)
)
(Echo Skipped unknown character '!c!'.)>&2
:break
If DEFINED line Goto :encode.loop
Echo;!codedLine!
Goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:decode
For /F %forParams% %%a in ('FindStr "^"') Do (
Set "line=%%a"
Call :decode
)
SetLocal EnableDelayedExpansion
Set "decodedLine="
:decode.loop
Set /A "n=0x%line:~0,2%"
Set "decodedLine=!decodedLine!!key:~%n%,1!"
Set "line=!line:~2!"
If DEFINED line Goto :decode.loop
Echo;!decodedLine!
Goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: END SCRIPT :::::::::::::::::::::::::::::::::::::::::::::::::::::::
Frank Westlake
12 years ago
Permalink
Post by f***@gmail.com
:decode
For /F %forParams% %%a in ('FindStr "^"') Do (
Set "line=%%a"
Call :decode
)
Dag nab it. Delete the FOR statement from the decode subroutine so that
those six lines become these two

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:decode

The rest of that subroutine remains as is. Call this version
2103-01-02-A. It still works properly with the extra FOR statement but
it is slower. I had the FOR statement in both :encode and :decode but
saw that they could be combined with the "which" variable and forgot to
remove one of the two.

Frank
dbenham
12 years ago
Permalink
[ code to obfuscate stdin (encode or decode) and write result to stdout ]
Nice Frank

One school of thought with obfuscation is to not worry about making it even moderately difficult to decode. So many use the ROT13 cipher for its convenience. It simply rotates the English alphabet 13 positions, and the same code can be used to both encode and decode the text. Numbers, punctuation, and non-English extended ASCII characters are left unchanged. It is very inconvenient to read the encoded text, so it achieves the goal of obfuscation. Perfect for embedding spoilers in a body of text. Only those that really want to know will take the time to decode the text.

Nearly 2 years ago I implemented batch ROT13 routines that operate on files and variables: http://www.dostips.com/forum/viewtopic.php?p=7028#p7028

Below I have adapted the code to use your idea of processing stdin instead. I added the FINDSTR /N option to preserve blank lines. It is quite fast for a batch script.

The cipher can be extended to encode additional characters like numbers and punctuation. But a few characters don't lend themselves well to the fast algorithm that I use. For example * and = would not work at all using the lookup methods I use, and " would be a pain because of quoting and escaping issues.

:: BEGIN SCRIPT ::::::::::::::::::::::::::::::::::
::
:: ROT13.BAT - Apply the ROT13 cipher to stdin and print the result to stdout
::
@echo off
setlocal disableDelayedExpansion
set "upper=#AAN#BBO#CCP#DDQ#EER#FFS#GGT#HHU#IIV#JJW#KKX#LLY#MMZ#NNA#OOB#PPC#QQD#RRE#SSF#TTG#UUH#VVI#WWJ#XXK#YYL#ZZM#"
set "lower=#aan#bbo#ccp#ddq#eer#ffs#ggt#hhu#iiv#jjw#kkx#lly#mmz#nna#oob#ppc#qqd#rre#ssf#ttg#uuh#vvi#wwj#xxk#yyl#zzm#"
for /f "delims=" %%a in ('findstr /n "^"') do (
set "str=%%a"
setlocal enableDelayedExpansion
set "str=A!str:*:=!"
set "len=0"
for /l %%A in (12,-1,0) do (
set /a "len|=1<<%%A"
for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"
)
set /a len-=1
set rtn=
set "str=!str:~1!"
for /l %%n in (0,1,!len!) do (
set "c=!str:~%%n,1!"
if "!c!" geq "a" if "!c!" leq "Z" (
for /f "delims=" %%c in ("!c!") do (
set "test=!upper:*#%%c=!"
if "!test:~0,1!"=="!c!" (
set c=!test:~1,1!
) else (
set "test=!lower:*#%%c=!"
if "!test:~0,1!"=="!c!" set c=!test:~1,1!
)
)
)
set "rtn=!rtn!!c!"
)
echo(!rtn!
endlocal
)
:: END SCRIPT ::::::::::::::::::::::::::::::::::::
Stanley Daniel de Liver
12 years ago
Permalink
...
[rot13 code snipped]

Here's my code from a decade or so ago;

rot13s.dbg

nrot13s.com
e100 BA 2F 1 8B F2 B9 1 0 EB 1C 8A 4 24 DF 3C 5A
e110 7F C 2C 41 7C 08 B4 D 3A C4 7C 2 F6 DC 0 24
e120 43 B4 40 CD 21 4B B4 3F CD 21 3A C1 74 DC C3 0
rcx
30
w
q


It takes text from stdio, so

debug <rot13s.dbg
echo Znetnerg Gungpure|rot13s.com


Jbex's under XP, NT and DOS
--
[dash dash space newline 4line sig]

Money/Life question
dbenham
12 years ago
Permalink
Post by Stanley Daniel de Liver
Here's my code from a decade or so ago;
[code creating .com file via debug snipped]
I'm sure that worked great and was screaming fast, but it doesn't do much good on modern Windows platforms ;)

An exe version would be nice.

Or a VBscript or Jscript version would also be very fast, and doesn't require any compilation.

But my goal was to create an optimized ROT13 implementation using nothing but native batch commands. Kind of silly, and not very practical, I know.


Dave Benham
Stanley Daniel de Liver
12 years ago
Permalink
Post by dbenham
Post by Stanley Daniel de Liver
Here's my code from a decade or so ago;
[code creating .com file via debug snipped]
I'm sure that worked great and was screaming fast, but it doesn't do
much good on modern Windows platforms ;)
It'll work as long as you can run a console; it's what I do in XP
(though there's a fairly tight limit on number of characters that can be
pasted into the buffer before you get beeps)
Post by dbenham
An exe version would be nice.
sorry I never wrote one, but I'm sure there's some out there - there's
certainly and addon to Thunderbird.
Paul Kretek wrote winrot13, but all the links I find are for "download
managers", not the s/w - it's about 350k

online:
http://rot13.com/
Post by dbenham
Or a VBscript or Jscript version would also be very fast, and doesn't
require any compilation.
But my goal was to create an optimized ROT13 implementation using
nothing but native batch commands. Kind of silly, and not very
practical, I know.
Quite. All good fun.
Post by dbenham
Dave Benham
--
[dash dash space newline 4line sig]

Money/Life question
foxidrive
12 years ago
Permalink
Post by Stanley Daniel de Liver
Post by dbenham
I'm sure that worked great and was screaming fast, but it doesn't do
much good on modern Windows platforms ;)
It'll work as long as you can run a console; it's what I do in XP
(though there's a fairly tight limit on number of characters that can be
pasted into the buffer before you get beeps)
This main issue you will see nowadays is that 64 bit windows can no longer run .com files.
And 64 bit is becoming very popular...
--
foxi
Andy
12 years ago
Permalink
Post by foxidrive
Post by Stanley Daniel de Liver
Post by dbenham
I'm sure that worked great and was screaming fast, but it doesn't do
much good on modern Windows platforms ;)
It'll work as long as you can run a console; it's what I do in XP
(though there's a fairly tight limit on number of characters that can be
pasted into the buffer before you get beeps)
This main issue you will see nowadays is that 64 bit windows can no longer run .com files.
And 64 bit is becoming very popular...
foxi
What Are the Advantages of 64 Bit Processors?
By Timothy Baron, eHow Contributor

In 2003, 64-bit processors were introduced to the mainstream market. Although not technically faster, the 64-bit architecture shows marked improvement in certain domains. To take full advantage of these qualities, though, users must not only purchase a 64-bit processor, but also acquire a 64-bit operating system. All versions of Windows from XP onward have a 64-bit variant, as do many versions of Linux.

How Do I Tell If I Have 32 Bit Windows XP?How Do I Tell If I Have 32 Bit Windows XP?
How Do I Know If I Have a 32-Bit or 64-Bit Processor?How Do I Know If I Have a 32-Bit or 64-Bit Processor?

More RAM

When operating with a 32-bit processor, Windows caps RAM usage at 4 gigabytes and in some cases even lower. Although 4GB is more than enough for many users' purposes, those operating memory-intensive software or high-end video games may find this maximum prohibitive. A 64-bit architecture allows you to push this limit up to a new maximum of 128GB. This feature is the single most dramatic difference between 32-bit and 64-bit architecture.
High-Precision Numerical Analysis

The 64-bit architecture is better suited to calculating large numbers. While the 32-bit architecture can accurately handle numbers of up to 32 digits, it is unable to fully process larger numbers. Over the course of multiple calculations, this can lead to fairly significant inaccuracies. In contrast, a 64-bit architecture can handle numbers up to 64 digits in length. Although this distinction is marginal for most users, those performing complex calculations on larger strings of data would encounter fewer errors in a 64-bit environment.
Faster Programs

Although a 64-bit architecture doesn't boost performance for all programs, it speeds up some programs significantly. This is especially true of programs that have been written to take advantage of a 64-bit environment. If your goal is to improve performance with a particular CPU-intensive program, first check to see if it has been tailored to 64-bit processing.


Read more: What Are the Advantages of 64 Bit Processors? | eHow.com http://www.ehow.com/list_5958344_advantages-64-bit-processors_.html#ixzz2HN7o06eo
Stanley Daniel de Liver
12 years ago
Permalink
Post by dbenham
Post by Stanley Daniel de Liver
Here's my code from a decade or so ago;
[code creating .com file via debug snipped]
I'm sure that worked great and was screaming fast, but it doesn't do
much good on modern Windows platforms ;)
An exe version would be nice.
Found Paul Kretek's winrot13 on Simtel;
http://www.simtel.net/free-download/Servers-News-Servers/winRot13/56301.html
Post by dbenham
Or a VBscript or Jscript version would also be very fast, and doesn't
require any compilation.
But my goal was to create an optimized ROT13 implementation using
nothing but native batch commands. Kind of silly, and not very
practical, I know.
Dave Benham
--
[dash dash space newline 4line sig]

Money/Life question
Andy
12 years ago
Permalink
...
You might want to put some error control in your code.

And if the input is not what is expected, give an error message.

Happy Coding.

Take care,
Andy
f***@gmail.com
12 years ago
Permalink
:: BEGIN SCRIPT :::::::::::::::::::::::::::::::::::::::::::::::::::::
:: From the desk of Frank P. Westlake, 2013-01-03
:: This item is being sold as a novelty only.
:: Batteries not included.
:? Obfuscates or deobfuscates standard input to standard output.
:? Version 2013-01-03 Preserves empty lines.
:? Version 2013-01-02 Original
:?
:? USAGE
:? obsufcate [/E | /D] [<key>]
:?
:? /E Encode input to output (default).
:? /D Decode input to output.
:? key An optional encoding key to replace the default.
:?
:? The default behavior is to encode input to output
using the internal
:? key. The internal key may be replaced by one on the
command line so
:? that it may remain secret and the character order
changable.
:?
:? The built-in key contains only the printable ASCII
characters but other
:? single byte characters may be added to it.
:?
:? EXAMPLES
:? TYPE bogus.cmd | obfuscate /D > good.cmd & good.cmd & DEL good.cmd
:? TYPE sample | obfuscate | obfuscate /d

@Echo OFF
SetLocal EnableExtensions DisableDelayedExpansion
:: DEFAULTS
Set "which=encode"
Set "TAB= "
Set "SP= "
For /F "delims=%SP%" %%a in ("1%TAB%") Do If "%%~a" EQU "1" (
(Echo %~nx0: The script's variable 'TAB' must be defined as a tab character.
Set /P "=LINE "<NUL:
FindStr /n /i /c:"TAB=" "%~f0"|FindStr /v "FindStr")>&2
Goto :EOF
)
Set "key=%tab%%sp%01234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm~`!@#$%%^&*()-_=+[{]}\|;:',<.>/?""
:args
:: ARGUMENTS
Set "$=%~1"
If DEFINED $ (
If "%$%" EQU "/?" (
SetLocal EnableDelayedExpansion
For /F "delims=" %%a in ('FindStr ":\?" %~f0') Do (
Set "$=%%a"
Echo;!$:~3!
)
EndLocal
Goto :EOF
)
If /I "%$%" EQU "/D" (
Set "which=decode"
) Else If /I "%$%" EQU "/E" (
Set "which=encode"
) Else (
Set "key=%~1"
)
SHIFT
Goto :args
)
:main
Set "hex=0123456789ABCDEF"
For /F "tokens=1 delims==" %%a in ('Set "$" 2^>NUL:') Do Set "%%a="
Set "$=%key%"
For /F "delims=:" %%a in (
'(SET $^& Echo.NEXT LINE^)^|FindStr /O "NEXT LINE"'
) Do Set /A "keyLength=%%a-4, keyLen=keyLength-1"
Set "forParams=delims^=^ eol^="
For /F %forParams% %%a in ('FindStr /N "^"') Do (
Set "line=%%a"
Call :%which%
)
Goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:encode
SetLocal EnableDelayedExpansion
Set "line=!line:*:=!"
If NOT DEFINED line (Echo;&Goto :EOF)
Set "codedLine="
:encode.loop
Set "c=!line:~0,1!"
Set "line=!line:~1!"
For /L %%i in (0 1 %keyLength%) Do (
If "!c!" EQU "!key:~%%i,1!" (
Set /A "hi=(%%i>>4)&0xF, lo=%%i&0xF"
For /F "tokens=1,2" %%j in ("!hi! !lo!") Do (
Set "codedLine=!codedLine!!hex:~%%j,1!!hex:~%%k,1!"
)
Goto :break
)
)
(Echo Skipped unknown character '!c!'.)>&2
:break
If DEFINED line Goto :encode.loop
Echo;!codedLine!
Goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:decode
SetLocal EnableDelayedExpansion
Set "line=!line:*:=!"
If NOT DEFINED line (Echo;&Goto :EOF)
Set "decodedLine="
:decode.loop
Set /A "n=0x%line:~0,2%"
Set "decodedLine=!decodedLine!!key:~%n%,1!"
Set "line=!line:~2!"
If DEFINED line Goto :decode.loop
Echo;!decodedLine!
Goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: END SCRIPT :::::::::::::::::::::::::::::::::::::::::::::::::::::::
Frank Westlake
12 years ago
Permalink
Post by f***@gmail.com
:? obsufcate [/E | /D] [<key>]
:?
:? /E Encode input to output (default).
:? /D Decode input to output.
:? key An optional encoding key to replace the default.
:?
:? The default behavior is to encode input to output using the internal
:? key. The internal key may be replaced by one on the command line so
:? that it may remain secret and the character order changable.
Here's an alternative to the option of providing the entire key on the
command line. Provide a pass-phrase on the command line and prefix the
internal key with the prefix. This prefix will offset the key an unknown
amount of places with unknown characters and the indexes of characters
in the pass-phrase will be used instead of indexes of duplicate
characters following them. For example, with this key (condensed for
space usage here):

Set "key=abcedfghijklmnopqrstuvwxyz"

and the pass-phrase "choo choo train", the key will effectively be as
follows, with the second line showing unused duplicates replaced with a
dash (-):

Set "key=choo choo trainabcedfghijklmnopqrstuvwxyz"
Set "key=cho- -----train-b-edfg--jklm--pq-s-uvwxyz"

With the pass-phrase prefix the internal key will be mostly useless to
anyone who happens to get a copy of it, and adding an unknown amount of
unknown characters adds to the security.

I think there is only one change to the script which is necessary to
Post by f***@gmail.com
:args
:: ARGUMENTS
Set "$=%~1"
If DEFINED $ (
If "%$%" EQU "/?" (
SetLocal EnableDelayedExpansion
For /F "delims=" %%a in ('FindStr ":\?" %~f0') Do (
Set "$=%%a"
Echo;!$:~3!
)
EndLocal
Goto :EOF
)
If /I "%$%" EQU "/D" (
Set "which=decode"
) Else If /I "%$%" EQU "/E" (
Set "which=encode"
) Else (
Set "key=%~1"
Change the above line to the following:

Set "key=%~1%key%"
Post by f***@gmail.com
)
SHIFT
Goto :args
)
Examples:

TYPE good.cmd | OBFUSCATE "Monkeys abound!" > bogus.cmd
TYPE bogus.cmd | OBFUSCATE /D "Monkeys abound!" > useful.cmd

Frank
Frank Westlake
12 years ago
Permalink
One problem that just occurred to me is that if the key is near or at
the maximum length then the pass-phrase will cause it to exceed the
maximum length. The maximum key length is 256 because I use two
hexadecimal places.

The script can be amended to use three places but that would make the
obfuscated files about another one-third larger in size. A second
alphabet could be used instead of the hexadecimal offsets but that would
make decoding take much longer. I thought that with today's drive space
the faster decodes would be preferred.

Frank
dbenham
12 years ago
Permalink
[ obfuscate code snipped ]
Frank

I've got some improvements for your obfuscator.

The biggest improvement is in performance.

The simplest change is to eliminate the CALL from your main loop, since that slows things down a lot. It is more code, but more efficient to let the :encode and :decode routines each have their own main loop, without iterating a CALL.

Also, your method of iterating the characters within each line via a GOTO loop is quite slow. It is much faster to use a fast string length algorithm and iterate via FOR /L.

Finally, the looping lookup method you use for encoding is inefficient. Dos tips user Aacini recently published an encoding method for ROT13 that is faster than the one I posted earlier, and it lends itself very well to your obfuscator: http://www.dostips.com/forum/viewtopic.php?p=23285#p23285

I've also added some new functionality.

I added options to allow specification of the key via a file or environment variable, in addition to allowing a string literal.

One other enhancement is to preserve characters that don't appear in the key by encoding them as themselves with a preceding space. With that enhancement, it is no longer critical that the key cover the entire character set found within the input. So I eliminated the TAB from the default key. It keeps things simpler.

I ran your original code as well as this modifed version against a ~78 kbyte file, and came up with the following timings:

Original Encode: 349.96 sec
Modified Encode: 39.85 sec 8.8 times faster

Original Decode: 182.01 sec
Modified Decode: 34.09 sec 5.3 times faster

::::::: BEGIN SCRIPT - Optimized Obfuscator ::::::::::::::::::::::::::::::::::::::::
:? Obfuscates or deobfuscates standard input to standard output.
:?
:? USAGE
:? obfuscate [option [value] ]...
:?
:? /E Encode stdin to stdout (default).
:? /D Decode stdin to stdout.
:? /K Key Specify the key as a string literal Key.
:? /V KeyVar Specify the name of a variable KeyVar that contains the key.
:? /F KeyFile Specify a file path KeyFile that contains the key.
:?
:? The default behavior is to encode input to output using the internal
:? key. The internal key may be replaced by one on the command line so
:? that it may remain secret and the character order changable.
:?
:? The built-in key contains all printable ASCII characters except TAB, but
:? other single byte characters may be added to it. Characters not found
:? in the key are encoded as themselves with a space in front.
:?
:? EXAMPLES
:? TYPE bogus.cmd | obfuscate /D > good.cmd & good.cmd & DEL good.cmd
:? TYPE sample | obfuscate | obfuscate /d

@echo off
setlocal enableExtensions disableDelayedExpansion

:: set defaults
set "/which=encode"
set "/key="
set "/keyType="

:args
if "%~1" neq "" (
if "%~1" equ "/?" (
for /f "delims=" %%A in ('findstr /bl ":?" %~f0') do (
set "out=%%A"
setlocal enableDelayedExpansion
(echo(!out:*?=!)
endlocal
)
exit /b 0
) else if /i "%~1" equ "/D" (
set "/which=decode"
) else if /i "%~1" equ "/E" (
set "/which=encode"
) else if /i "%~1" equ "/K" (
if "%~2" neq "" (
set "/key=%~2"
set "/keyType=literal"
shift /1
) else >&2 echo Option error: Missing /K key string
) else if /i "%~1" equ "/V" (
if "%~2" neq "" (
set "/key=%~2"
set "/keyType=variable"
shift /1
) else >&2 echo Option error: Missing /V variable name
) else if /i "%~1" equ "/F" (
if "%~2" neq "" (
set "/key=%~2"
set "/keyType=file"
shift /1
) else >&2 echo Option error: Missing /F file name
) else (
&2 echo Invalid option: %1
)
shift /1
goto :args
)
if "%/keyType%" equ "file" (
setlocal enableDelayedExpansion
if exist "!/key!" (
for /f usebackq^ delims^=^ eol^= %%A in ("!/key!") do (
endlocal
set "/key=%%A"
goto :break
)
) else (
&2 echo Error: Key file "!/key!" not found
endlocal
set "/key="
)
)
:break
if "%/keyType%" equ "variable" (
setlocal enableDelayedExpansion
if defined !/key! (
for /f delims^=^ eol^= %%A in ("!/key!") do (
for /f delims^=^ eol^= %%B in ("!%%A!") do (
endlocal
set "/key=%%B"
)
)
) else (
&2 echo Error: Key variable "!/key!" not defined
endlocal
set "/key="
)
)
if not defined /key set ^"/key=" 0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm~`!@#$%%^&*()-_=+[{]}\|;:',<.>/?"
goto %/which%

:encode
for /f "delims==" %%A in ('set $ 2^>nul') do set "%%A="
setlocal enableDelayedExpansion
set /a len=0
for /l %%b in (12,-1,0) do (
set /a "len|=1<<%%b"
for %%c in (!len!) do if "!/key:~%%c,1!" equ "" set /a "len&=~1<<%%b"
)
endlocal & set "len=%len%"
set "hex=0123456789ABCDEF"
set "lower=abcdefghijklmnopqrstuvwxyz"
for /l %%N in (0 1 %len%) do (
set /a "h1=%%N/16, h2=%%N%%16"
setlocal enableDelayedExpansion
for /f "tokens=1,2" %%A in ("!h1! !h2!") do set "code=!hex:~%%A,1!!hex:~%%B,1!"
set "char=!/key:~%%N,1!"
for %%A in (!code!) do for /f delims^=^ eol^= %%C in ("!char!") do (
if "!char!" equ "=" (
endlocal & set "$equal=%%A"
) else if "!char!" equ "^!" (
endlocal & set "$bang=%%A"
) else if "!lower:%%C=%%C!" neq "!lower!" (
endlocal & set "$upper%%C=%%A"
) else endlocal & set "$lower%%C=%%A"
)
)
for /f delims^=^ eol^= %%A in ('findstr /n "^"') do (
set "in=%%A"
set "out="
setlocal enableDelayedExpansion
set "in=!in:*:=!"
if defined in (
set /a len=0
for /l %%b in (12,-1,0) do (
set /a "len|=1<<%%b"
for %%c in (!len!) do if "!in:~%%c,1!" equ "" set /a "len&=~1<<%%b"
)
for /l %%b in (0 1 !len!) do (
set "char=!in:~%%b,1!"
set "code="
if "!char!" equ "=" (
set "code=!$equal!"
) else if "!char!" equ "^!" (
set "code=!$bang!"
) else for /f delims^=^ eol^= %%C in ("!char!") do (
if "!lower:%%C=%%C!" neq "!lower!" (
set "code=!$upper%%C!"
) else set "code=!$lower%%C!"
)
if defined code (set "out=!out!!code!") else set "out=!out! !char!"
)
)
(echo(!out!)
endlocal
)
exit /b 0

:decode
setlocal enableDelayedExpansion
for /f "tokens=1* delims=:" %%A in ('findstr /n "^"') do (
set "in=%%B"
set "out="
if defined in (
set /a len=0
for /l %%b in (12,-1,0) do (
set /a "len|=1<<%%b"
for %%c in (!len!) do if "!in:~%%c,1!" equ "" set /a "len&=~1<<%%b"
)
for /l %%b in (0,2,!len!) do (
set /a "pos=0x!in:~%%b,2!" 2>nul && (
for %%c in (!pos!) do set "out=!out!!/key:~%%c,1!"
) || (
set "char=!in:~%%b,2!"
set "out=!out!!char:* =!"
)
)
)
(echo(!out!)
)
exit /b 0
::::::: END SCRIPT - Optimized Obfuscator ::::::::::::::::::::::::::::::::::::::::::

I also created another version that swaps characters instead of encoding as hex pairs. It allows specification of your own key, just like your original obfuscator. This obfuscator also uses Aacini's fast lookup method. This one uses the same code to encode and decode, and the decoded output is the same size as the input. It supports 2 modes of obfuscation. The first one is symmetric, like ROT13. But instead of rotating, it swaps the outer most characters for each other, and swaps the 2nd with the penultimate, etc.

The 2nd mode allows the user to specify a rotation delta to apply to the characters. If 15 is used to encode, then -15 is used to decode. With this option, there are 2 pieces of information that a user must know in order to decode data - the key, and the delta.

This obfuscator is able to encode and decode the ~78 kbyte file in 35 seconds.

::::::: BEGIN SCRIPT - Swapping Obfuscator :::::::::::::::::::::::::::::::::::::::
:? Obfuscates or deobfuscates standard input to standard output.
:?
:? USAGE
:? obfuscate [/option optionValue ]...
:?
:? The valid options are:
:? /D Delta The Delta to use for a rotation cipher.
:? /K Key Specify the key as a string literal Key.
:? /V KeyVar Specify the name of a variable KeyVar that contains the key.
:? /F KeyFile Specify a file path KeyFile that contains the key.
:?
:? The default behavior is to use a symmetric cipher - If the input is encoded
:? it will decode it. If the input is un-encoded it will encode it. The default
:? cipher swaps the 1st and last characters in the key, the 2nd and next to last
:? characters, etc.
:?
:? The /D option switches to a rotation cipher, with Delta specifying how much
:? to rotate each character position. Negate the Delta to decode the input.
:?
:? The default behavior is to encode or decode using a key internal to the
:? script. The internal key may be replaced by one on the command line so
:? that it may remain secret and the character order changable.
:?
:? The built-in key contains all printable ASCII characters except 'TAB',
:? but other single byte characters may be added. Characters not found in the
:? key are left unchanged.
:?
:? The key must not have any duplicate characters.
:?
:? EXAMPLES:
:?
:? 1) Run an obfuscated batch script.
:?
:? TYPE bogus.bat | obfuscate > good.bat & good.bat & DEL good.bat
:?
:? 2) Encode and decode the input for no change to make sure everything works.
:?
:? TYPE sample | obfuscate | obfuscate
:? TYPE sampel | obfuscate /d 17 | obfuscate /d -17
:?
@echo off
setlocal enableExtensions disableDelayedExpansion

:: set defaults
set "/key="
set "/keyType="
set "/delta="

:args
if "%~1" neq "" (
if "%~1" equ "/?" (
for /f "delims=" %%A in ('findstr /bl ":?" %~f0') do (
set "out=%%A"
setlocal enableDelayedExpansion
(echo(!out:*?=!)
endlocal
)
exit /b 0
) else if /i "%~1" equ "/D" (
set /a "_delta=%~2"
shift /1
) else if /i "%~1" equ "/K" (
if "%~2" neq "" (
set "/key=%~2"
set "/keyType=literal"
shift /1
) else >&2 echo Option error: Missing /K key string
) else if /i "%~1" equ "/V" (
if "%~2" neq "" (
set "/key=%~2"
set "/keyType=variable"
shift /1
) else >&2 echo Option error: Missing /V variable name
) else if /i "%~1" equ "/F" (
if "%~2" neq "" (
set "/key=%~2"
set "/keyType=file"
shift /1
) else >&2 echo Option error: Missing /F file name
) else (
&2 echo Invalid option: %1
)
shift /1
goto :args
)
if "%/keyType%" equ "file" (
setlocal enableDelayedExpansion
if exist "!/key!" (
for /f usebackq^ delims^=^ eol^= %%A in ("!/key!") do (
endlocal
set "/key=%%A"
goto :break
)
) else (
&2 echo Error: Key file "!/key!" not found
endlocal
set "/key="
)
)
:break
if "%/keyType%" equ "variable" (
setlocal enableDelayedExpansion
if defined !/key! (
for /f delims^=^ eol^= %%A in ("!/key!") do (
for /f delims^=^ eol^= %%B in ("!%%A!") do (
endlocal
set "/key=%%B"
)
)
) else (
&2 echo Error: Key variable "!/key!" not defined
endlocal
set "/key="
)
)
if not defined /key set ^"/key=" 0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm~`!@#$%%^&*()-_=+[{}]\|;:',<.>/?"

:encode
for /f "delims==" %%A in ('set $ 2^>nul') do set "%%A="
setlocal enableDelayedExpansion
set /a len=0
for /l %%b in (12,-1,0) do (
set /a "len|=1<<%%b"
for %%c in (!len!) do if "!/key:~%%c,1!" equ "" set /a "len&=~1<<%%b"
)
endlocal & set "len=%len%"
set "delta="
if defined _delta set /a "keyLen=len+1, _delta=_delta%%keyLen"
set "lower=abcdefghijklmnopqrstuvwxyz"
set "dupErr=(>&2 echo Error: Duplicate character '%%C' found in key&goto :dupErr)"
for /l %%N in (0 1 %len%) do (
setlocal enableDelayedExpansion
if defined _delta (
set /a "swap=(%%N+_delta+keyLen)%%keyLen"
) else set /a "swap=len-%%N"
set "char=!/key:~%%N,1!"
for %%A in (!swap!) do set "swap=!/key:~%%A,1!"
for /f delims^=^ eol^= %%S in ("!swap!") do for /f delims^=^ eol^= %%C in ("!char!") do (
if "!char!" equ "=" (
endlocal & if defined $equal %dupErr% else set "$equal=%%S"
) else if "!char!" equ "^!" (
endlocal & if defined $bang %dupErr% else set "$bang=%%S"
) else if "!lower:%%C=%%C!" neq "!lower!" (
endlocal & if defined $upper%%C %dupErr% else set "$upper%%C=%%S"
) else (
endlocal & if defined $lower%%C %dupErr% else set "$lower%%C=%%S"
)
)
)
goto :continue
:dupErr
for /f "delims==" %%A in ('set $ 2^>nul') do set "%%A="
:continue
for /f delims^=^ eol^= %%A in ('findstr /n "^"') do (
set "in=%%A"
set "out="
setlocal enableDelayedExpansion
set "in=!in:*:=!"
if defined in (
set /a len=0
for /l %%b in (12,-1,0) do (
set /a "len|=1<<%%b"
for %%c in (!len!) do if "!in:~%%c,1!" equ "" set /a "len&=~1<<%%b"
)
for /l %%b in (0 1 !len!) do (
set "char=!in:~%%b,1!"
if "!char!" equ "=" (
if defined $equal set "char=!$equal!"
) else if "!char!" equ "^!" (
if defined $bang set "char=!$bang!"
) else for /f delims^=^ eol^= %%C in ("!char!") do (
if "!lower:%%C=%%C!" neq "!lower!" (
if defined $upper%%C set "char=!$upper%%C!"
) else if defined $lower%%C set "char=!$lower%%C!"
)
set "out=!out!!char!"
)
)
(echo(!out!)
endlocal
)
exit /b 0
::::::: END SCRIPT - Swapping Obfuscator :::::::::::::::::::::::::::::::::::::::


Dave Benham
billious
12 years ago
Permalink
Post by dbenham
[ obfuscate code snipped ]
Frank
I've got some improvements for your obfuscator.
The biggest improvement is in performance.
[snip...]
Post by dbenham
Dave Benham
I'm rather amused by the amount of effort being applied to this exercise
- the object of which is to deliberately confuse...
Frank Westlake
12 years ago
Permalink
Post by billious
I'm rather amused by the amount of effort being applied to this exercise
- the object of which is to deliberately confuse...
Yes, but why?

Frank
f***@gmail.com
12 years ago
Permalink
:: BEGIN SCRIPT :::::::::::::::::::::::::::::::::::::::::::::::::::::
:: From the desk of Frank P. Westlake, 2013-01-03
:: Package not marked for individual sale.
:: This script will randomize the contents of the string contained in
:: the vaiable "key", set below, and set the new string into the
:: clipboard. The resulting string will begin with the string "$="
:: which must be removed before eating. Also, the same string will
:: be printed to the console window but the tab character will be
:: converted to 1-8 spaces.
@Echo OFF
SetLocal EnableExtensions DisableDelayedExpansion
Set "TAB= "
Set "SP= "
For /F "delims=%SP%" %%a in ("1%TAB%") Do If "%%~a" EQU "1" (
(Echo %~nx0: The script's variable 'TAB' must be defined as a tab character.
Set /P "=LINE "<NUL:
FindStr /n /i /c:"TAB=" "%~f0"|FindStr /v "FindStr")>&2
Goto :EOF
)
Set "out="
Set "key=%tab%%sp%0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm~`!@#$%%^&*()-_=+[{]}\|;:',<.>/?""
For /F "tokens=1 delims==" %%a in ('Set "$" 2^>NUL:') Do Set "%%a="
Set "$=%key%"
For /F "delims=:" %%a in (
'(SET $^& Echo.NEXT LINE^)^|FindStr /O "NEXT LINE"'
) Do Set /A "length=%%a-4, len=length-1"
SetLocal EnableDelayedExpansion
For /L %%a in (0,1,%len%) Do (
Set /A "i=!RANDOM! %% length, j=i+1, length-=1"
REM Echo "i=!i! , j=!j!, length=!length!"
For /F "tokens=1-2" %%i in ("!i! !j!") Do (
Set "out=!out!!$:~%%i,1!"
Set "$=!$:~0,%%i!!$:~%%j!"
)
)
Set "$=!out!"
Set $|"%SystemRoot%\system32\clip.exe"
Set $
EndLocal
EndLocal
Todd Vargo
12 years ago
Permalink
...
Frank, your disclaimers are cute but...

FYI, I have XPpro-sp3 but clip.exe does not exist here. As a courtesy to
the readers when using external utilities in a batch, it is prudent to
state the OS intended/tested and if the externals are not part of the OS.
--
Todd Vargo
(Post questions to group only. Remove "z" to email personal messages)
f***@gmail.com
12 years ago
Permalink
Post by Todd Vargo
Post by f***@gmail.com
Set $|"%SystemRoot%\system32\clip.exe"
FYI, I have XPpro-sp3 but clip.exe does not exist here.
As a courtesy to the readers when using external
utilities in a batch, it is prudent to state the OS
intended/tested and if the externals are not part of the
OS.
You are correct. My apologies. That was my procedure
long ago and I shall return to it. But all I can do is
state the OS my scripts were written on because I don't
know when MicroSoft started including which external
commands. The only reason I gave the full path to
clip.exe is because I wrote a clip.exe long before
MicroSoft did and it exists in my path prior to the
system32 directory.

MicroSoft should do a factory recall on all their NT
operating systems and update them to the most recent
state. After all, we don't own the software -- it still
belongs to Microsoft. It isn't hardware that would
require an exchange of materials, it isn't even anything
real -- it only a pattern of bits. There is no valid
reason why a person who purchased a license to use an
operating system for a certain computer should not be
given improvements to that computer's operating system
until the computer is no longer able to support them, or
they should refund the license.

While I have the floor:

The key randomized by this script should be adjusted a
little. The double quote within the string should be
moved so that it is after all special characters and the
percent sign should be doubled. The simplest format is:

SET "key=all characters except quote""

Note that there are two terminating double-quotes. I
think this is read two different ways by CMD but the
application here is that one terminates the entire
quoted string and the other is a character within the
quoted string.

Frank
Andy
12 years ago
Permalink
...
Without providing clip.exe, the script is not useful to anyone else.

It's good making improvements to an O.S.

Andy
Continue reading on narkive:
Loading...