I'm writing a batch code that when prompted will write a .bat file. This is an example of the code I'm using to create the .bat:
echo set /a num=0 >>%fileinfo%.bat
echo :repeat1 >>%fileinfo%.bat
echo set /a num=%num% +1 >>%fileinfo%.bat
echo echo %num% >>%fileinfo%.bat
echo if %num%==100 goto end >>%fileinfo%.bat
echo goto repeat1 >>%fileinfo%.bat
This is the original code:
set /a num=0
:repeat1
set /a num=%num% +1
echo %num%
if %num%==100 goto end
goto repeat1
What happens when I run the code and create the new .bat:
set /a num=0
:repeat1
set /a num= +1
echo
if ==100 goto end
goto repeat1
It takes out the %num%, can anyone think of a way around this or an alternative method to create the file? Thanks.
echo set /a num=0 >>%fileinfo%.bat
echo :repeat1 >>%fileinfo%.bat
echo set /a num=%%num%% +1 >>%fileinfo%.bat
echo echo %%num%% >>%fileinfo%.bat
echo if %%num%%==100 goto end >>%fileinfo%.bat
echo goto repeat1 >>%fileinfo%.bat
#ECHO OFF
SETLOCAL
SET "fileinfo=q20296357x"
(
echo set /a num=0
echo :repeat1
echo set /a num=%%num%% +1
echo echo %%num%%
echo if %%num%%==100 goto end
echo goto repeat1
)>>%fileinfo%.bat
TYPE %fileinfo%.bat
GOTO :EOF
Your fundamental problem is that %var% is replaced by the CONTENTS of var before the line is executed. For some characters which have a special meaning to batch like the redirectors >|< you need to prefix the special character with ^.
Bizarrely, to "escape" %, the escape charater is not ^ but % itself - so each literal % needs to be coded as %%
Note how your code can be condensed by parenthesising the ECHOs and redirecting to your target file.
Note also that you could also code ...goto :EOF instead of ...goto end if you actually want to go to the end-of-file. eof is a magic label - batch understands it to be end-of-file so it should not be declared in your batch. Case is not important, but the colon is required.
Related
I want to make a batch obfuscator with no outside tools, but I have a problem with echoing the spaces into the 'obfuscated' code('obfuscated' as in separating the code letter by letter between hundreds of random characters). I have found batch obfuscators that are used with CertUtil, but they can be de-obfuscated with another file, so I really want to get this working, and I haven't really found any unique ones.
When I run my file with the input file (contains #echo off and echo test), I get the obfuscated code:
$zz$j?$z?$#z#?$z?$z###$j?j#zz?$?##j$?$?$#z$$#zjj#zzz?j#jzj#zjjzj?$#$jj?j##z##?#$$$#zjz?$zj#j$zz#jzj###$z#j#j#??##zj#z#j$?$jzjz?$j?$?##zzz#???z$$jzj#??###jz$?$j$z$?$?$?j$j?$jzzj#j#z$zz$jzz#z#$jz#?z?$$$?e$?$j?$##?#zjjjjz#j$$zjjz##$?jzjj?$##?##j$#z#zj?zzjzj$$j#$j$????$z#j#$?j?#j$$$$#jzj$$j#z#z###?j#zjz#jc$#jjz$j#$zj?#z$$?j$z$#?zz$$zz#z?##j#zz#j#z##?$#z$j?$j?z$#?#$$z??j?zj#j$##?#$zz#$$$z?z$z?jz#?j?j#z$?jhj??z?zzj##$?#j$$j#j?#$?$j$$zzzzjjz?z?##$?$$j$zz#?j#?##z#jz$z#jz$z?zzj$###z#jzjzz$##?$j??$??#?zz##?$$ojj#$j$j##?#?jzj$z#?zz##$jjjj#j#?$##j?$?j$#jzzj#?$?jz#$#z#$j???z#$?z?jzzzj$?#jzj#j$#j#??j$?jj?jzz?$#$##z$jjj#?jjz#??jz$?###$j$##$$#$$#?$?j$?z$j?j##?z$#jj?#jzjjjzz$jzjj$##z$?#$##z#$#z##$z?zz##$z?jj$#??jo#$##jjjj?$z$?#z?$##zjz$#j#zz#z?$#$##$j#j?#$#$zz$zj#j?$jjz#jjzjjz#$$j#jjz$?z?j?j#?j$#?zj?jjzzz#$?$##jfzj#?##?jjzjjz$??#zjj??j#????#z#$$$?$?##z$#$zj?jj?#?z$jzj?$j?#??zzj#$jj$?z#j???jjj#$jj$###?$$##jjz?$jf$$##z$$?jjj$##z$$jz#z#z?#j##$?$$##z?z$z$$$#jj$?zj?#jz#z$jz?$#j$?#j##z$$jz?$z$$?z#?jz?$$zz$$$#$$?#jjjjz?zj?$$j?#$#?jjj?$$?j$$$#??j?zzz#?zjz$jjzz$?zjz##j#$?z#z$??$?$?jj?###jj##$zjjj$z$?###z#z$??z#jz#zjz?$?j#j$j#zj??j#z??z$$z#$$$$##z$?#?$$jjjj#zz#j###?j??z#$#$$?j##z#$#$$z#jjzj#$#jjjz?###$???zzzz$#$z?j$$$#??z?#j$j$???z?$jz$z?z???z?j#j??$z$$#$#$#j??$$##zjj#j#$$z$$?jj?jzjzjz$$z#zz?$?j$zjzjzz$j#j$#??j???jjj##z#$$$#j$#?j?#z$#$?#zj#?$$??jj?#z#?$##jzzz?$$$zjjjzzjz#$#?#$#jz$z?$z##jjjzj?z?j???j??##$zj$zj?#zjzj##j#z$$???#$jzj#z?z??jj##??z####?#?#z??j$????$$zz#jzj?z?j?z?#z$zz??j$?zz#jj##zz##??zj?#z??$?j###?zz#zjjzj$$z#??#?$?#$jj#j?$$$j?zzjz?$?#z#z$#jj#jz$???zj$jjjz$jz#j#$zz?jj#jj?#jj###?z#$j?zzj#jz?$#zj?#?j#?z??$z??jzz?#zj??j?$z##z#j$zjz#zz?$zj$?jjz?jjj$?j$$#z#?#j?zj$$j#jj#z?z#j#?jzzz$jjj$jzjz$j#j#j#?zzzz??z#z$jz#$#z$$?jz$j#?jz??jj#jj$z#z##j$j$##$???z??j?zzjz$??j#zzz#$jj#jzj#z$z$$?$z$jzzj#$#z$#z?z$###???$$?zz$#??j$?$j#j$#?zj$jzzj??j?z?zzz##?j$?z?j$jjz$jj?z#?j##$$?zjzjj#jjj??z$?#zzj$j#??z#zz$$j?jzj#j
$zz$j?$z?$#z#?$z?$z###$j?j#zz?$?##j$?$?$#z$$#zjj#zzz?j#jzj#zjjzj?$#$jj?j##z##?#$$$#zjz?$zj#j$zz#jzj#e#$z#j#j#??##zj#z#j$?$jzjz?$j?$?##zzz#???z$$jzj#??###jz$?$j$z$?$?$?j$j?$jzzj#j#z$zz$jzz#z#$jz#?z?$$$?c$?$j?$##?#zjjjjz#j$$zjjz##$?jzjj?$##?##j$#z#zj?zzjzj$$j#$j$????$z#j#$?j?#j$$$$#jzj$$j#z#z###?j#zjz#jh$#jjz$j#$zj?#z$$?j$z$#?zz$$zz#z?##j#zz#j#z##?$#z$j?$j?z$#?#$$z??j?zj#j$##?#$zz#$$$z?z$z?jz#?j?j#z$?joj??z?zzj##$?#j$$j#j?#$?$j$$zzzzjjz?z?##$?$$j$zz#?j#?##z#jz$z#jz$z?zzj$###z#jzjzz$##?$j??$??#?zz##?$$jj#$j$j##?#?jzj$z#?zz##$jjjj#j#?$##j?$?j$#jzzj#?$?jz#$#z#$j???z#$?z?jzzzj$?#jzj#j$#j#??j$?jj?jzz?$#$h##z$jjj#?jjz#??jz$?###$j$##$$#$$#?$?j$?z$j?j##?z$#jj?#jzjjjzz$jzjj$##z$?#$##z#$#z##$z?zz##$z?jj$#??ji#$##jjjj?$z$?#z?$##zjz$#j#zz#z?$#$##$j#j?#$#$zz$zj#j?$jjz#jjzjjz#$$j#jjz$?z?j?j#?j$#?zj?jjzzz#$?$##jzj#?##?jjzjjz$??#zjj??j#????#z#$$$?$?##z$#$zj?jj?#?z$jzj?$j?#??zzj#$jj$?z#j???jjj#$jj$###?$$##jjz?$j$$##z$$?jjj$##z$$jz#z#z?#j##$?$$##z?z$z$$$#jj$?zj?#jz#z$jz?$#j$?#j##z$$jz?$z$$?z#?jz?$$zz$$$#$$?#jjjjz?zj?$$j?#$#?jjj?$$?j$$$#??j?zzz#?zjz$jjzz$?zjz##j#$?z#z$??$?$?jj?###jj##$zjjj$z$?###z#z$??z#jz#zjz?$?j#j$j#zj??j#z??z$$z#$$$$##z$?#?$$jjjj#zz#j###?j??z#$#$$?j##z#$#$$z#jjzj#$#jjjz?###$???zzzz$#$z?j$$$#??z?#j$j$???z?$jz$z?z???z?j#j??$z$$#$#$#j??$$##zjj#j#$$z$$?jj?jzjzjz$$z#zz?$?j$zjzjzz$j#j$#??j???jjj##z#$$$#j$#?j?#z$#$?#zj#?$$??jj?#z#?$##jzzz?$$$zjjjzzjz#$#?#$#jz$z?$z##jjjzj?z?j???j??##$zj$zj?#zjzj##j#z$$???#$jzj#z?z??jj##??z####?#?#z??j$????$$zz#jzj?z?j?z?#z$zz??j$?zz#jj##zz##??zj?#z??$?j###?zz#zjjzj$$z#??#?$?#$jj#j?$$$j?zzjz?$?#z#z$#jj#jz$???zj$jjjz$jz#j#$zz?jj#jj?#jj###?z#$j?zzj#jz?$#zj?#?j#?z??$z??jzz?#zj??j?$z##z#j$zjz#zz?$zj$?jjz?jjj$?j$$#z#?#j?zj$$j#jj#z?z#j#?jzzz$jjj$jzjz$j#j#j#?zzzz??z#z$jz#$#z$$?jz$j#?jz??jj#jj$z#z##j$j$##$???z??j?zzjz$??j#zzz#$jj#jzj#z$z$$?$z$jzzj#$#z$#z?z$###???$$?zz$#??j$?$j#j$#?zj$jzzj??j?z?zzz##?j$?z?j$jjz$jj?z#?j##$$?zjzjj#jjj??z$?#zzj$j#??z#zz$$j?jzj#j
However, when I manually remove all of the characters, I am left with:
#echooff
echotest
Is there a way to echo spaces into a file by itself so this problem will be fixed?
My code:
#echo off
set /a N=0
:file
set /p "file=Enter filename: "
if not exist %file% echo Please try again. The file you specified does not exist.
if not exist %file% pause>nul
if not exist %file% cls
if not exist %file% goto file
cls
echo Please wait.
set /a overallfirst=1
set /a double=0
for /F "usebackq tokens=*" %%f in ("%file%") do goto start
:start
set /a "tamp=%random%"
set /a loop2=0
set /a rand=%random% %%5 +1
if %rand%==1 echo #> %tamp%
if %rand%==2 echo $> %tamp%
if %rand%==3 echo ?> %tamp%
if %rand%==4 echo z> %tamp%
if %rand%==5 echo j> %tamp%
:chars
if %loop2%==100 goto next
set /a rand=%random% %%5 +1
if %rand%==1 <nul set /p=#>> %tamp%
if %rand%==2 <nul set /p=$>> %tamp%
if %rand%==3 <nul set /p=?>> %tamp%
if %rand%==4 <nul set /p=z>> %tamp%
if %rand%==5 <nul set /p=j>> %tamp%
set /a loop2+=1
goto chars
:next
for /f "usebackq tokens=*" %%f in ("%tamp%") do set chars=%%f
set "start=^<nul set /p=%chars%^>^> Obfuscated.bat"
del %tamp%
set /a loop=-1
set /a first=1
for %%i in (%file%) do #set count=%%~zi
echo #echo off> Chars.bat
if %double%==0 echo empty^> Obfuscated.bat>> Chars.bat
echo for /f "tokens=*" %%%%a in (%file%) do set id=%%%%a ^& call :processline %%%%a >> Chars.bat
echo cls>>Chars.bat
echo echo Obfuscated code:>>Chars.bat
echo echo -------------------------->>Chars.bat
echo type Obfuscated.bat>>Chars.bat
echo pause^>nul>>Chars.bat
echo exit >> Chars.bat
echo goto :eof >> Chars.bat
echo :processline >> Chars.bat
:loop
set /a loop=%loop%+1
if %loop%==%count% goto end
if %first%==1 set first=0 & goto other
set "command=^<nul set /p=%%id:~%loop%,1%%"
echo %command%^>^> Obfuscated.bat>> Chars.bat
goto next1
:other
set "command=%start%"
echo %command%>> Chars.bat
set /a loop=%loop%-1
goto loop
:next1
set /a "tamp=%random%"
set /a loop2=0
set /a rand=%random% %%5 +1
if %rand%==1 echo #> %tamp%
if %rand%==2 echo $> %tamp%
if %rand%==3 echo ?> %tamp%
if %rand%==4 echo z> %tamp%
if %rand%==5 echo j> %tamp%
:chars
if %loop2%==100 goto next2
set /a rand=%random% %%5 +1
if %rand%==1 <nul set /p=#>> %tamp%
if %rand%==2 <nul set /p=$>> %tamp%
if %rand%==3 <nul set /p=?>> %tamp%
if %rand%==4 <nul set /p=z>> %tamp%
if %rand%==5 <nul set /p=j>> %tamp%
set /a loop2+=1
goto chars
:next2
for /f "usebackq tokens=*" %%f in ("%tamp%") do set chars=%%f
set "command=^<nul set /p=%chars%"
echo %command%^>^> Obfuscated.bat>> Chars.bat
del %tamp%
goto loop
:end
echo echo. ^>^> Obfuscated.bat>> Chars.bat
echo goto :eof >> Chars.bat
echo :eof >> Chars.bat
start Chars.bat
if %overallfirst%==1 set /a overallfirst=0 & set /a double=1
I have looked for a solution, but I was unable to find one.
(I am fairly new to Batch coding so this script is not very efficient)
Try using <nul set /p and echo/. This post may help: Preserve spaces with <Nul set /p
Im making an rpg game in batch, and here is the code for the stat system so far
:SPSPEND
CLS
Echo You have %SP% stat points to spend, every stat point used increases that skill by 5.
Echo 1. Strength=%Strength%
Echo 2. Agility=%Agility%
Echo 3. Magic=%Magic%
Echo 4. Vitality=%MaxHP%
Echo 5. Defence=%Defence%
Echo 6. Archery=%Archery%
set /p choice=Choose what to put points into:
if %choice%=="1" Set /a Strength==%strength%+5
if %choice%=="2"
if %choice%=="3"
if %choice%=="4"
if %choice%=="5"
if %choice%=="6"
cls
set /a SP==%SP%-1
goto :rest
Not sure how to format soz. i need help with two things : how can i make it so that it doesnt close out and actually works, and how can i make a failsafe incase a person enters something other than what i already have set up.
Thanks in advance
I believe this is what you want.
I have tested it and am fairly certain it will work
:SPSPEND
CLS
if %SP% leq 0 goto end
Echo You have %SP% stat points to spend, every stat point used increases that skill by 5.
Echo 1. Strength=%Strength%
Echo 2. Agility=%Agility%
Echo 3. Magic=%Magic%
Echo 4. Vitality=%MaxHP%
Echo 5. Defence=%Defence%
Echo 6. Archery=%Archery%
set /p choice=Choose what to put points into:
if "%choice%"=="1" Set /a Strength=%Strength%+5& set /a SP=%SP%-1& goto SPSPEND
if "%choice%"=="2" Set /a Agility=%Agility%+5& set /a SP=%SP%-1& goto SPSPEND
if "%choice%"=="3" Set /a Magic=%Magic%+5& set /a SP=%SP%-1& goto SPSPEND
if "%choice%"=="4" Set /a MaxHP=%MaxHP%+5& set /a SP=%SP%-1& goto SPSPEND
if "%choice%"=="5" Set /a Defence=%Defence%+5& set /a SP=%SP%-1& goto SPSPEND
if "%choice%"=="6" Set /a Archery=%Archery%+5& set /a SP=%SP%-1& goto SPSPEND
echo invalid choice
pause
goto SPSPEND
cls
:end
pause
goto :rest
I'm 90% of the way there on a Windows Batch file.
It takes 2 input parameters, input and output files.
It then reads in the input file, and substrings certain lines into arrays (Well line 2 onwards).
Then we come to a loop for outputting.
With delayed expansion on my counter for going through the array doesn't update unless I use !counter2!, %counter2% doesn't work.
Using !arrayname[!counter2!]! doesn't work.
Here is the code as it stands.
#Echo off
if [%1] == [] goto usage
if [%2] == [] goto usage
echo start time : %time%>logfile.log
set input_file=%1
set output_file=%2
if exist %output_file% del %output_file%
Echo Start reading %input_file%>> logfile.log
setLocal EnableDelayedExpansion
set /a counter=1
for /F "tokens=* delims=" %%a in ('type %input_file%') DO (
::echo !counter!
if "!counter!"=="1" set header=%%a
if not "!counter!"=="1" (
set data[!counter!]=%%a
set line=%%a
set jobnumber[!counter!]=!line:~0,7!
set docnumber[!counter!]=!line:~7,5!
set pagecount[!counter!]=!line:~12,2!
set customernumber[!counter!]=!line:~14,20!
set presort[!counter!]=0000
set postcode[!counter!]=0000
set inserts[!counter!]=!line:~36,11!
set filler[!counter!]=000000
set address[!counter!]=!line:~58,350!
set filler2[!counter!]=" "
set endline[!counter!]=X
)
set /a counter=counter+1
)
Echo Start writing %output_file%>> logfile.log
for /L %%G in (2,1,%counter%) DO (
set counter2=%%G
echo !counter2!
echo !jobnumber[%counter2%]!!docnumber[%counter2%]!!pagecount[%counter2%]!!customernumber[%counter2%]!!presort[%counter2%]!!postcode[%counter2%]!!inserts[%counter2%]!!filler[%counter2%]!!address[%counter2%]!!filler2[%counter2%]!!endline[%counter2%]!>>%output_file%
)
echo end time : %time%>>logfile.log
pause
goto :eof
:usage
echo Usage: blah.bat input_filename output_filename
pause
goto :eof
It is the echo !jobnumber[%counter2%]! where things are not being resolved.
The echo !counter2! works fine.
Before you ask, Yes I know this could be done better and easier in C# or another programming language, However I am tasked with doing it in a windows batch file.
Thanks in advance for any help provided.
Tel
Try with:
for /L %%G in (2,1,%counter%) DO (
set counter2=%%G
echo !counter2!
echo !jobnumber[%%G]!!docnumber[%%G]!!pagecount[%%G]!!customernumber[%%G]!!presort[%%G]!!postcode[%%G]!!inserts[%%G]!!filler[%%G]!!address[%%G]!!filler2[%%G]!!endline[%%G]!>>%output_file%
)
You are not changing the value of the coutner2 so you don't need it and you can directly use %%G.
Though if you need changes in counter2 you'll have to wrap it again in for loop and to use its tokens.
I want to but this in to an other .bat file
echo %random% > test.bat
set /a num= +1
:repeat1
set /a num= +1
echo %random% >> test.bat
if ==100 goto end
goto repeat1
So I have tried with this:
echo echo %every%%random%%random%%random%%random% > "output.txt" > test.bat
echo set /a num=%num% +1 >> test.bat
echo :repeat1 >> test.bat
echo set /a num=%num% +1 >> test.bat
echo echo %every%%random%%random%%random%%random% >> "output.txt" >> test.bat
echo if %num%==%amount% goto end >> test.bat
echo goto repeat1 >> test.bat
:end >> test.bat
But the %% things don't work (it will put a random nummer but I want to have %random% in the new .bat file
you have to escape some chars if you want to write them literally. Most of them are escaped with a caret ^ (&,<,>,|). The percent sign is an exception: it is escaped with another percent-sign:`
echo %%random%% ^> test.bat
But may I suggest another method to write your second bat file (without caring for characters to escape):
#echo off
for /f "delims=:" %%i in (' findstr /n /c:":: Start of Second ::" "%~dpnx0"') do set start=%%i
more +%start% "%~dpnx0" >test.bat
call test.bat
echo -------
type test.txt
echo -------
goto :eof
:: Start of Second ::
#echo off
echo %random% >test.txt
set /a num=0
:repeat1
set /a num+=1
echo %random% >>test.txt
if %num%==10 goto :eof
goto .repeat1
The for is used to determine the start line of the data to be written,
more +n writes the file ("~dpnx0" is the currently running batchfile) by skipping the first n lines.
Pro: no need to escape anything - just write the data as it should be outputted.
Contra: only one "second file" possible; only static text possible.
I am trying to make a random string in batch, and I have no idea what to do. I have called a random string of numbers with the %random% function, but I have no idea how to permanently replace certain characters in my variable:
#echo off
set subkey1=%random%%random%%random%%random%%random%%random%
set subkey2=%random%%random%%random%%random%%random%%random%
set subkey3=%random%%random%%random%%random%%random%%random%
ECHO %subkey1:0=a%
ECHO %subkey1:1=b%
ECHO %subkey1:2=c%
ECHO %subkey1:3=d%
ECHO %subkey1:4=e%
ECHO %subkey1:5=f%
ECHO %subkey1:6=g%
ECHO %subkey1:7=h%
ECHO %subkey1:8=i%
ECHO %subkey1:9=j%
ECHO %subkey2:0=k%
ECHO %subkey2:1=l%
ECHO %subkey2:2=m%
ECHO %subkey2:3=n%
ECHO %subkey2:4=o%
ECHO %subkey2:5=p%
ECHO %subkey2:6=q%
ECHO %subkey2:7=r%
ECHO %subkey2:8=s%
ECHO %subkey2:9=t%
ECHO %subkey3:0=u%
ECHO %subkey3:1=v%
ECHO %subkey3:2=w%
ECHO %subkey3:3=x%
ECHO %subkey3:4=y%
ECHO %subkey3:5=z%
REM after going through all the letters, we just pick random ones
ECHO %subkey3:6=a%
ECHO %subkey3:7=g%
ECHO %subkey3:8=k%
ECHO %subkey3:9=o%
set key=%subkey1%%subkey2%%subkey3%
echo String: %key%
pause
So as you can see, I am able to ECHO different keys, but I want to save the new one to the variable (EX in subkey 1, I wanna replace all the 0s by a's, then SAVE that so if I look at my variable afterwards, I can see the new one, and be able to call that in different functions.
same effect with much less code:
#echo off
setlocal enabledelayedexpansion
set "string=abcdefghijklmnopqrstuvwxyz"
set "result="
for /L %%i in (1,1,30) do call :add
echo %result%
goto :eof
:add
set /a x=%random% %% 26
set result=%result%!string:~%x%,1!
goto :eof
To assign a variable a value, use the SET command:
SET subkey1=%random%%random%%random%%random%%random%%random%
SET subkey1=%subkey1:0=a%
SET subkey1=%subkey1:1=b%
SET subkey1=%subkey1:2=c%
.
.
.
ECHO %subkey1%
And, of course, beware that %random% should never, ever be used as a source for cryptographic purposes.
#echo off
setlocal EnableDelayedExpansion
set charSets=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!##$%^&*
set count=0
set /a countRaw=4+(%random%)%%20
for /L %%c in (1,1,%countRaw%) do (call :MAKERANDOMSTRING)
goto ENDRANDOMSTRING;
:MAKERANDOMSTRING
set buffer=% %
set count=0
set /a lowValue=30+(%random%)%%40
set /a length=10+!lowValue!
:Loop
set /a count+=1
set /a rand=%Random%%%69
set buffer=!buffer!!charSets:~%rand%,1!
if !count! leq !length! goto Loop
echo "%buffer%"
:ENDRANDOMSTRING