Noob
Noob

Reputation: 534

Store a file inside of a batch file?

I'm trying to store a binary file inside of a basic batch script that ive written. Basically i want the script to be able to output this prebuilt file at some point instead of creating it from scratch.

If this is not possible then i would have to include this file separately with the batch file which would then move it into the necessary location, but I'd rather have this file invisible to the user so that it seems that the file is being generated from within the batch.

So is this possible and if so how?

Upvotes: 7

Views: 6442

Answers (3)

npocmaka
npocmaka

Reputation: 57262

CERTUTIL

The foxidriive's answer will work but it can be improved with much more less IO operations. When decoding base64 file certutil cares only about the begin and end tags. Here;s an example that will create and open a small jpg file:

@echo off

del /q /f pointer.jpg >nul 2>nul
certutil -decode "%~f0" pointer.jpg
hh.exe pointer.jpg
exit /b %errorlevel%

-----BEGIN CERTIFICATE-----
/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAMgAA/+4ADkFkb2Jl
AGTAAAAAAf/bAIQACAYGBgYGCAYGCAwIBwgMDgoICAoOEA0NDg0NEBEMDg0NDgwR
DxITFBMSDxgYGhoYGCMiIiIjJycnJycnJycnJwEJCAgJCgkLCQkLDgsNCw4RDg4O
DhETDQ0ODQ0TGBEPDw8PERgWFxQUFBcWGhoYGBoaISEgISEnJycnJycnJycn/8AA
EQgACgAKAwEiAAIRAQMRAf/EAFsAAQEBAAAAAAAAAAAAAAAAAAAGBwEBAQAAAAAA
AAAAAAAAAAAAAAEQAAIBAwQDAAAAAAAAAAAAAAEDAgARBSExIwQSIhMRAQEBAAAA
AAAAAAAAAAAAAAARIf/aAAwDAQACEQMRAD8A13PZ5eIX3gO8ktKZfFPksvQ8r4uL
ecJmx1BMSbm8D6UVKVcg/9k=
-----END CERTIFICATE-----

IEXPRESS

You can use IEXPRESS to create self-extracting executable that packs the needed binaries ,a bat file and execute the packed file. You can use directives or the defauled UI mode by just invoking the command.

Alternate data streams

you can store data in an alternate data stream and then read it with powershell. Mind that most text editors will remove the ADS:

@echo off
del new.jpg /f /q >nul 2>&1
chcp  65001
type pointer.jpg >"%~f0:bindata"
powershell "$data=Get-Content -path """%~f0"""  -stream bindata;Out-File -FilePath '.\new.jpg' -InputObject $data -Encoding unicode;"
exit /b %errorlevel%

Upvotes: 3

jeb
jeb

Reputation: 82317

You could simply append the binary part to your batch file with COPY.

copy /a batchBin.bat + /b myBinaryFile.bin /b combined.bat

batchBin.bat (The last line with exit /b should end with a newline)

    ;;;===,,,@echo off
    ;;;===,,,echo line2
    ;;;===,,,findstr /v "^;;;===,,," "%~f0" > output.bin
    ;;;===,,,exit /b

The key is the findstr command, it outputs all lines not beginning with ;;;===,,,.
And as each of them are standard batch delimiters, they can be prefix any command in a batch file in any combination.

Upvotes: 16

foxidrive
foxidrive

Reputation: 41244

If the target machine is Vista and higher then you can use certutil.exe and create a base64 encoded text, which you can embed within the batch file.

This example has a base64 encoded file that is just a single space, but the technique is the same with larger binaries.

This batch file uses certutil.exe to decode the certificate and data and create the file with a single space in it, no carriage return or line feed.

@echo off
(
echo -----BEGIN CERTIFICATE-----
echo IA==
echo -----END CERTIFICATE-----
)>file.tmp
certutil -decode file.tmp "file with a single space.txt" >nul
del file.tmp

To encode a program file for placing inside the batch file you use a command line like this, replacing myprogram.exe with your program name:

certutil -encode -f "myprogram.exe" file.tmp

and then place the contents of file.tmp inside the batch file:

@echo off
(
echo -----BEGIN CERTIFICATE-----
echo place the data from file.tmp here
echo as it is listed inside the file
echo -----END CERTIFICATE-----
)>file.tmp
certutil -decode file.tmp "myprogram.exe" >nul
del file.tmp

It's fairly easy to add the echo to the front of each line and then use the data from file2.tmp:

@echo off
for /f "delims=" %%a in (file.tmp) do >>file2.tmp (echo(echo %%a)

Upvotes: 9

Related Questions