@echo off set ERL=1 REM ---------- Begin OS Check echo. if "%OS%"=="Windows_NT" goto :isWinNT echo Das Betriebsystem ist nicht WinNTx pause exit /b exit :isWinNT VERIFY OTHER 2>nul SETLOCAL ENABLEEXTENSIONS IF ERRORLEVEL 1 ( set errMSG=Befehlserweiterungen konnten nicht aktiviert werden. goto :ERR ) VERIFY OTHER 2>nul setlocal ENABLEDELAYEDEXPANSION IF ERRORLEVEL 1 ( set errMSG=Die verz”gerte Erweiterung von Umgebungsvariablen wurde nicht aktiviert. goto :ERR ) REM ---------- End OS Check setlocal set inpFi=%~1 set outFiPart=installer set progDD=dd.exe set progGREP=grep.exe set progLZMA=lzma.exe set progSFK=sfk.exe set searchBytes=5D00008000 set version=0.6 set title=Spoon-Installer Extractor by Limer - ver.%version% VERIFY OTHER 2>nul echo %CMDCMDLINE% | %SystemRoot%\System32\find.exe /I /C "/C" >nul set cmdClose=%ERRORLEVEL% title %title% REM Check if all required programms are available. set ERL=0 for %%I IN ("%progDD:"=%" "%progGREP:"=%" "%progLZMA:"=%" "%progSFK:"=%") do ( set /A ERLtmp=!ERL! if "%%~xI" EQU "" ( set /A ERL+=1 REM ERL-=1 could happen >1 times (x.exe, x.com, ...). FOR %%B IN (%PathExt%) DO FOR %%A IN ("%%~nI%%B") DO if "%%~$PATH:A" NEQ "" set /A ERL-=1 ) else ( if "%%~$PATH:I" EQU "" set /A ERL+=1 ) if !ERL! GTR !ERLtmp! set errMSG=Required programm "%%~I" could not be found ^(!ERL!^). ) if %ERL% GTR 0 goto :ERR set ERL=0 REM missing interactiv input if no inpFi set errMSG=Input not defined. if not defined inpFi goto :ERR REM Check input and change drive/path. set /A ERL=-1 for %%I IN ("%inpFi%") do if exist "%%~I" if "%%~dI" NEQ "\\" ( set /A ERL+=1 set fiSize=%%~zI set inpFi=%%~fI set inpFiName=%%~nI set inpFiExt=%%~xI %%~dI cd %%~pI if ".exe" NEQ "%%~xI" set /A ERL+=1000000 ) set errMSG=Too many, no local or no (.exe-)file(s) specified ("%inpFi%"). if %ERL% NEQ 0 goto :ERR REM check if %inpFi% is a spooninstaller (or rather if it contains lzma-archive headers) REM Missing: use of trid set errMSG="%inpFi%" is no SpoonInstaller. %progSFK% hexfind "%inpFi%" -nodump -bin /%searchBytes%/ > nul if not %ERRORLEVEL% EQU 1 goto :ERR REM check if dir/opject exists and if it's a directory or a file, ask for adwise :chk_inpFiNameDir if not exist "%inpFiName%" goto :continue for %%I IN ("%inpFiName%") do set inpFiNameDirAtr=%%~aI if /I "D" NEQ "%inpFiNameDirAtr:~0,1%" ( set inpFiName=%inpFiName%_%RANDOM% goto :chk_inpFiNameDir ) echo. echo The directory "%CD%\%inpFiName%" echo does already exist. echo Press [ENTER] to use it anyway (files may be overwritten). echo Or enter sth. else to quit. echo. set inp= set /P inp= Input: if defined inp goto :EOFi :continue mkdir "%inpFiName%" >nul 2>&1 cd "%inpFiName%" REM Find the offsets of %searchBytes% in the file. set offsets= && echo off set cntFinds=0 for /F "usebackq tokens=3 delims=:" %%I IN (`%progSFK% hexfind "%inpFi%" -quiet -bin /%searchBytes%/ ^| %progGREP% -i ": hit at offset "`) do ( set tmpH2D=%%~I REM remove " hit at offset "(15) from %%I and convert the 0xXXXX... to decimal set /A tmpH2D=!tmpH2D:~15! if !tmpH2D! EQU 0 ( set /A ERL+=1 echo. echo I="%%I" and tmpH2D="!tmpH2D!" ) set offsets=!tmpH2D! !offsets! set /A cntFinds+=1 ) set errMSG=Error retriving offsets (%ERL% zeros, %cntFinds% finds). if %ERL% NEQ 0 goto :ERR if not %cntFinds% GTR 1 goto :ERR REM Extract the lzma parts from the inpFi and expand them. title %title% - Extracting "%inpFiName%%inpFiExt%" set cntPart=%cntFinds% set upLimit=%fiSize% for %%I IN (%offsets%) do ( echo. echo Proccessing part #!cntPart! set /A byteCnt=!upLimit! - %%I set upLimit=%%I REM starting from %%I copy !byteCnt! bytes to stdout and read lzma archive from stdin to unpack it. %progDD% bs=1 count=!byteCnt! if="%inpFi%" skip=%%I 2>nul | %progLZMA% d -si "%outFiPart%_!cntPart!.out" >nul 2>&1 if not exist "%outFiPart%_!cntPart!.out" set /A ERL+=1 set /A cntPart-=1 ) set errMSG=Differences between #parts and #finds (%cntPart% NEQ 0). if %cntPart% NEQ 0 goto :ERR set errMSG=Error extracting (%ERL%). if %ERL% NEQ 0 goto :ERR title %title% - Extracting finished move /Y "%outFiPart%_%cntFinds%.out" "%outFiPart%_script.txt" move /Y "%outFiPart%_1.out" "%outFiPart%_picture.bmp" move /Y "%outFiPart%_2.out" "%inpFiName%_license.txt" REM Get the name and path of each file and rename/move accordingly. REM missing check if "%outFiPart%_script.txt" is a spooninstallerscript? set cntREN=3 set cntClean=0 for /F "usebackq tokens=1,* delims=>" %%I IN (`%progGREP% -i --after-context=2 \[CopyFile\] "%outFiPart%_script.txt" ^| %progGREP% -i destination`) do ( set tmpFIname=%%~J if "!tmpFIname:~0,1!" EQU "\" set tmpFIname=!tmpFIname:~1! REM clean if exist "!tmpFIname!" ( set /A cntClean+=1 del /F /Q "!tmpFIname!" 2>nul rmdir /Q /S "!tmpFIname!" 2>nul ) REM create dir if "!tmpFIname:\=!" NEQ "!tmpFIname!" ( mkdir "!tmpFIname!" 2>nul rmdir "!tmpFIname!" 2>nul ) move "%outFiPart%_!cntREN!.out" "!tmpFIname!" if %ERRORLEVEL% NEQ 0 echo.&&echo "%outFiPart%_!cntREN!.out" could not be moved to "!tmpFIname!". if not exist "!tmpFIname!" set /A ERL+=1 set /A cntREN+=1 ) if %cntClean% GTR 0 echo.&&echo.&&echo %cntClean% Files overwritten. set errMSG=Renaming the files failed (%ERL%). if %ERL% NEQ 0 goto :ERR set errMSG=Crazy error: RenameCNT GTR FindsCNT (%cntREN% GTR %cntFinds%) if %cntFinds% LSS %cntREN% goto :ERR set errMSG=Everything is fine but not all files where renamed (ae. "%outFiPart%_%cntREN%.out"). if %cntFinds% GTR %cntREN% goto :ERR title %title% - Renaming/moving finished echo. echo All done. goto :EOFi :ERR title %title% - ERROR echo. echo. echo The following Error occured: echo %ERRMSG% echo. :EOFi cd.. if %ERL% NEQ 0 if exist "%inpFiName%" rmdir "%inpFiName%" 2>nul if "%cmdClose%"=="0" ( echo. echo. echo -- End -- pause ) exit /B %ERL% How it works: 1. SFK checks if file-headers from lzma-archives are present. 2. SFK/GREP provide the offsets of those headers. 3. DD extracts the lzma-archives to stdout. 4. LZMA reads the stdout from DD and expands the archives. 5. GREP looks for "[CopyFile]" inside the SpoonInstaller_script (last extracted file) and delivers the right names & paths required to create the directories and move the renamed files. Required programms: - "dd" from http://www.chrysocome.net/dd/ or from on of the grep sources. - "grep" from http://unxutils.sourceforge.net/ or from http://gnuwin32.sourceforge.net/packages/grep.htm - "lzma" from http://www.7-zip.org/sdk.html or you can use "7za"/"7z + 7z.dll" if you rewrite the extraction process in here (7z cant read archives from stdin) - "SFK" from http://swissfileknife.sourceforge.net/ ToDo: 1. Allow interactiv input if no file passed to the .cmd 2. improve the filetype checking (realy a spoon installer?) first lines: 5D00 0080 00xx xx00 0000 0000 0000 ^^works for all? second lines: 2696 8E70 0017 F7EC 05BB EAF4 FF94 012F 44EF ^^works for exes 2113 42C6 ADEE D751 D5F3 BB69 3F90 DAA1 D450 ^^works for bmps