7

Hi im 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? Thanks in advance.

Mark
  • 3,609
  • 1
  • 22
  • 33
Noob
  • 534
  • 1
  • 8
  • 16
  • A batch file is plain text. It can't contain a "binary file". – Ken White Oct 24 '13 at 20:48
  • 5
    [Creating .EXE auxiliary programs in Batch files](http://www.dostips.com/forum/viewtopic.php?f=3&t=3202) – Endoro Oct 24 '13 at 21:02
  • 2
    @KenWhite A batch file can contain a binary part, but it's probalby better to use Aacinis technic described in the above link – jeb Oct 25 '13 at 09:23
  • 1
    @jeb - Sure the batch file can contain binary data at the end, after some marker. but I don't see how a batch script can extract the binary data and write it to a file using only native commands. But then, you didn't say it could be done, did you ;-) You only stated the binary content can be embedded within the batch script. – dbenham Oct 25 '13 at 15:21
  • 1
    @dbenham It can be solved, see [my answer](http://stackoverflow.com/a/19596027/463115). There is a very mighty built in tool and a good description at [findstr](http://stackoverflow.com/a/8844873/463115) ;-) – jeb Oct 25 '13 at 17:31

4 Answers4

14

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.

jeb
  • 78,592
  • 17
  • 171
  • 225
  • 3
    +1, Ooh - tricky. I thought of FINDSTR, but I was stuck on figuring out how to distinguish the batch script from the binary code. I forgot you can harmlessly preface each script line with any number of token delimiters. It even works with label lines `;;;===,,, :label`. Very nice – dbenham Oct 25 '13 at 17:45
  • `findstr /v` has a limit on line lengths so might work with small binaries. I've noticed for video files I get error: `FINDSTR: Line 3613257 is too long.` – Zimba Mar 18 '21 at 12:26
9

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)
foxidrive
  • 40,353
  • 10
  • 53
  • 68
3

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%
npocmaka
  • 55,367
  • 18
  • 148
  • 187
2

Read about HERE documents. Msdos batch does not offer them, but perl and ruby are both available and do.

http://en.wikipedia.org/wiki/Here_document

ChuckCottrill
  • 4,360
  • 2
  • 24
  • 42
  • Perl and Ruby are not commonly available. If you're going for a solution like this, you might just as well (or better) grab a programming language that allows you to build a self-contained executable that can also include this file. Or maybe even use a self-extracting archive. – GolezTrol Oct 24 '13 at 20:52
  • I assumed the OP wanted a script language. Perl and Ruby do not require compilation, and are fairly easy to install. Python works also. – ChuckCottrill Oct 24 '13 at 20:56