Page 1 of 1

A simple way to join/unjoin files

Posted: 05 Jun 2018 01:54
by Bucko
There is a simple way to concatenate files by a DOS command:

Code: Select all

copy /a Batch.bat + /b Binary.exe /b Combined.bat       *)
An there is a way to "unconcatenate" such a Combined.bat by a DOS command: If Batch.bat consists only of lines starting with e.g. ";;==,," (this doesn't affect the execution of the bat!), the following Unjoin.bat using only the findstr command extracts the Binary.exe from the Combined.bat:

Code: Select all

findstr /v "^;;==,," Combined.bat > BinaryExtracted.exe
This command "ignores" all "lines" of the Combined.bat not starting with ";;==,," and outputs only the binary part. My experience is that this works perfectly, findstr extracts exactly the original Binary.exe.

Now to my question: Could findstr (or maybe antoher DOS command) be used to unjoin a file generated in such a way, with a Delimiter.txt containing only a line with ";;==,,".:

Code: Select all

copy /b Binary1.exe + /a Delimiter.txt + /b Binary2.exe + /a Delimiter.txt + /b Binary3.exe /b Combined.exe
The Unjoin.bat should extract Binary1.exe, Binary2.exe, ...

Is this possible?

Thank you very much in advance.




*) Or:

Code: Select all

copy /b Binary.exe + /a Batch.bat /b Combined.exe
The difference is: In the first example starting Combined.bat runs Batch.bat, in the second example starting Combined.exe runs Binary.exe.
And generally, of course, the file joined with Batch.bat can be any type of binary or text file.

Re: A simple way to join/unjoin files

Posted: 05 Jun 2018 21:30
by Bucko
If the above is impossible or too complex, at least the following should be achieved:

If Combined.exe contains only one delimiter string:

Code: Select all

copy /b Binary1.exe + /a Delimiter.txt + /b Binary2.exe /b Combined.exe
only the binary part after this string (Binary2.exe) should be extracted. That means that findstr should "ignore" not only all lines starting with ";;==,," but also all lines preceeding the first occurence of such a line.

Re: A simple way to join/unjoin files

Posted: 08 Jun 2018 02:27
by penpen
Your algorithm has a possible weaknesses against the string "\r\n;;==,," (c++-notation; '\r'==carriage return, '\n'== newline), because it might be part of any executable:
You should test the executable you want to join for that string, and if it is contained abort the joining process.

Bucko wrote:
05 Jun 2018 01:54
Could findstr (or maybe antoher DOS command) be used to unjoin a file generated in such a way, with a Delimiter.txt containing only a line with ";;==,,".:

Code: Select all

copy /b Binary1.exe + /a Delimiter.txt + /b Binary2.exe + /a Delimiter.txt + /b Binary3.exe /b Combined.exe
The Unjoin.bat should extract Binary1.exe, Binary2.exe, ...

Is this possible?
Actually i don't know a console/gui command that is able to display data until a special delimiter (except the "copy/a" and "type" commands, which both stops at the first SUB character - but it only can be used up to the first SUB character).

You maybe could use dave's "JREPL.BAT" - if that's an option for you:
viewtopic.php?f=3&t=6044.

Or you might use certutil to create a base64 string and use a line with characters that are no base64 codepoints (or something like that).


penpen

Re: A simple way to join/unjoin files

Posted: 09 Jun 2018 08:07
by Bucko
Thank you very much, penpen!

The delimiter string was just an example, of course a more sofisticated string can be used.

Yes, findstr is able to process binary "strings"! There are some limitations, but the method works.

I see that nobody here can give me an answer, so I posted a new question limited to a specific aspect of my problem:
viewtopic.php?f=3&t=8613
Maybe this will be more successful.

Re: A simple way to join/unjoin files

Posted: 11 Jun 2018 20:32
by Aacini
If you are willing to use an additional .exe file (not findstr.exe), then this problem may be solved in a very simple way.

Some time ago I wrote an auxiliary program called ReadFile.exe that can read a certain number of bytes from a redirected file handle. Using this program you may split a large file in several segments based on the size of each one, so it is not necessary to include any kind of delimiter between binary files.

This is JoinFiles.bat:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem Join/Unjoin binary files in a Batch file
rem The created program requires ReadFile.exe auxiliary file
rem Antonio Perez Ayala

if "%~1" neq "" goto begin
echo Usage: %0 binFile1 binFile2 ...
echo/
echo Creates MakeFiles.bat file that will extract the files given in the parameters
goto :EOF

:begin

rem Create the self-extracting Batch file
echo These files will be joined:
set "i=0"
set "files="
(
   rem Header of the Batch file
   echo @echo off
   echo setlocal EnableDelayedExpansion
   echo set "file[0]=NUL"

   rem Names and sizes of joined files
   for %%f in (%*) do (
      if exist %%f (
         set /A i+=1
         echo !i!- %%f (%%~Zf bytes^)> CON
         echo set "file[!i!]=%%~f"
         echo set "size[!i!]=%%~Zf"
         set "files=!files! + /B "%%~f""
      ) else (
         echo File not found: %%f > CON
      )
   )

   rem Code to extract files
   echo ^< "%%~F0" ( for /L %%%%i in (0,1,!i!^) do ReadFile 0 ^^^!size[%%%%i]^^^! ^> "^!file[%%%%i]^!" ^)
   echo goto :EOF

) > Temp.txt

rem Get the size of the Batch code. It will include an additional first line with this format:
rem @set "size[0]=9999"
rem that is, 19 characters plus CR+LF at end = 21
for %%f in (Temp.txt) do set /A "size=%%~Zf+21"
set "size=   %size%"

rem Create the final Batch file 
(
   echo @set "size[0]=%size:~-4%"
   type Temp.txt
) > MakeFiles.bat
del Temp.txt

rem Add the joined files
copy /A MakeFiles.bat %files% /B MakeFiles.bat > NUL
echo MakeFiles.bat file created
ReadFile.exe program is included in "Auxiliary .exe programs.zip" file; you may download it from this thread. Such a .zip file includes many other useful auxiliary .exe programs.

Or you may download just ReadFile.exe program from the next .zip file:

ReadFile.zip
(744 Bytes) Downloaded 359 times

Antonio