Sign in to follow this  
Followers 0
stormbreaker

CD/DVD (El Torito) Boot image extractor

4 posts in this topic

#1 ·  Posted (edited)

;) Hello everyone. 3 days back, I came across "El Torito" Bootable CD-ROM Format Specification. I was able to write this simple script to extract Boot-Image from a CD/DVD/ISO file. Here is it:

#include <WinAPI.au3>

Global $nBytes
ConsoleWrite("Boot-Image X-tract (by MKISH)" & @crlf & @crlf & "USAGE: bootext.exe <PATH> <IMGNAME>")
If $CmdLine[0] = 0 then Exit
If NOT FileExists($CmdLine[1]) then Exit

$PATH = $CmdLine[1]
$RESULT = $CmdLine[2]

$hFile = _WinAPI_CreateFile("." & $PATH, 2,2)
$xBuffer = DllStructCreate("byte["& 4 & "]")
_WinAPI_SetFilePointer($hFile, 0x11*0x800 + 0x47)
_WinAPI_ReadFile($hFile, DllStructGetPtr($xBuffer), 4, $nBytes)
$sText1 = DllStructGetData($xBuffer, 1)

$dBuffer = DllStructCreate("byte["& 4 & "]")
_WinAPI_SetFilePointer($hFile, 0x800 * Int($sText1) + 0x20 + 0x8)
_WinAPI_ReadFile($hFile, DllStructGetPtr($dBuffer), 4, $nBytes)
$sText2 = DllStructGetData($dBuffer, 1)

$fBuffer = DllStructCreate("byte["& 1 & "]")
_WinAPI_SetFilePointer($hFile, 0x800 * Int($sText1) + 0x20 + 1)
_WinAPI_ReadFile($hFile, DllStructGetPtr($fBuffer), 1, $nBytes)
$sTextd = DllStructGetData($fBuffer, 1)

$pBuffer = DllStructCreate("byte["& 2 & "]")
_WinAPI_SetFilePointer($hFile, 0x800 * Int($sText1) + 0x20 + 0x6)
_WinAPI_ReadFile($hFile, DllStructGetPtr($pBuffer), 2, $nBytes)
$sText3 = SecCount()
$zBuffer = DllStructCreate("byte[" & $sText3 * 0x200 & "]")
_WinAPI_SetFilePointer($hFile, 0x800 * Int($sText2))
_WinAPI_ReadFile($hFile, DllStructGetPtr($zBuffer), $sText3 * 0x200, $nBytes)
$sText4 = DllStructGetData($zBuffer, 1)
FileWrite("" & $RESULT, $sText4)
_WinAPI_CloseHandle($hFile)

Func SecCount()
$fBuffer = DllStructCreate("byte["& 1 & "]")
_WinAPI_SetFilePointer($hFile, 0x800 * Int($sText1) + 0x20 + 1)
_WinAPI_ReadFile($hFile, DllStructGetPtr($fBuffer), 1, $nBytes)

Switch DllStructGetData($fBuffer, 1)
Case 0x00
Return Int(DllStructGetData($pBuffer, 1))

Case 0x01
Return Int(0x50 * 0x02 * 0x0F)

Case 0x02
Return Int(0x50 * 0x02 * 0x12)

Case 0x03
Return Int(0x50 * 0x02 * 0x24)
EndSwitch

EndFunc

Just compile this as CUI App. Hope it is of use to somebody. Useful suggestions are welcome.

EDIT:

The link is working now. A bugfix

Edited by MKISH
1 person likes this

----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Share this post


Link to post
Share on other sites



FIX: Just bored so fixed this minor bug - the script sometimes printed NULL characters for CD images.

----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Share this post


Link to post
Share on other sites
UPDATE: Now going command-line.... complete. Posted the command-line version (see 1st post)

----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • czyt
      By czyt
      May it helps those who needed.
       
      #include <WinAPI.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _IsUEFIBoot ; Description ...: Detemine the Current OS is boot in UEFI mode or not ; Syntax ........: _IsUEFIBoot() ; Parameters ....: ; Return values .: True:OS is boot in UEFI ; False: OS is boot in Legacy BIOS ; Author ........: czyt ; Modified ......: ; Remarks .......: ; Related .......: http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WinBatch/DllCall~Information+Booted~UEFI~or~BIOS.txt ; Link ..........: ; Example .......: MsgBox(0,'(*^__^*) The OS is in UEFI Boot mode?',_IsUEFIBoot()) ; =============================================================================================================================== Func _IsUEFIBoot() Local Const $ERROR_INVALID_FUNCTION=0x1 DllCall("Kernel32.dll", "dword", "GetFirmwareEnvironmentVariableW", "wstr", "", "wstr", '{00000000-0000-0000-0000-000000000000}', "wstr", Null, "dword", 0) If _WinAPI_GetLastError() = $ERROR_INVALID_FUNCTION Then Return False Else Return True EndIf EndFunc  
    • MadDogVachon
      By MadDogVachon
      Hi everyone,
      Here is my script that does the job of the original BootSectGui. I wrote it because I needed a BootSectGui that works in WinPE x64 environment. The original works only in x86 envoronment. It is free to use, modify and distribute. I coded first in French and then in English, it may have some mistranslation.
      In the 7z attached file you have these files:
      BootSectGui - original - Main.png    ->  The original Main window of BootSectGui BootSectGui - original - Log.png     ->  The original Log window of BootSectGui BootSectGui - original.exe               ->  The original BooSectGui.exe program BootSectGui_x86_x64.au3              ->  My code BootSectGui_x86.exe                      ->  My program x86 version 1.3 BootSectGui_x64.exe                      ->  My program x64 version 1.3 BootSectGui_x86_x64 1.2.1.au3     ->  My code for 1.2.1 BootSectGui_x86 1.2.1.exe             ->  My program 1.2.1 x86 version
      BootSectGui_x64 1.2.1.exe             ->  My program 1.2.1 x64 version BootSectGui_x64 - Main.png          ->  My Main window
      BootSectGui_x64 - Log.png            ->  My Log window BootSectGui_x64 - Main 1.2.1.png  ->  My Main window 1.2.1
      BootSectGui.psd                             ->  My "code" for the ico files in Photoshop format BootSectGui BSG 64.ico                 ->  The icon used with my program, in 64 dots BootSectGui BSG 256.ico               ->  The same in 256 dots BootSectGui G BS 64.ico                ->  Another icon that looks more like the original one, in 64 dots BootSectGui G BS 256.ico              ->  The same in 256 dots Enjoy!
      MDV
      Here's the code:
      #RequireAdmin #region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=BootSectGui BSG 64.ico #AutoIt3Wrapper_Compile_Both=y #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Compression=4 #AutoIt3Wrapper_Res_Comment=New BootSectGui #AutoIt3Wrapper_Res_Description=New BootSectGui that works in WinPE x86 and x64 #AutoIt3Wrapper_Res_Fileversion=1.3 #AutoIt3Wrapper_Res_SaveSource=y #AutoIt3Wrapper_Run_Obfuscator=y #Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0 #AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_Obfuscated.au3" #endregion ;**** Directives created by AutoIt3Wrapper_GUI **** #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.8.1 Author: MadDogVachon Script Function: A Gui for BootSect that work in WinPE x64 environment (also in WinPE x86 and Windows x86 x64) Thanks to AZJIO for the improvement of my code! #ce ---------------------------------------------------------------------------- #include <GuiConstantsEx.au3> #include <Constants.au3> #include <GuiEdit.au3> #include <GuiConstantsEx.au3> #include <ComboConstants.au3> #include <WindowsConstants.au3> Opt('MustDeclareVars', 1) Local $Title = "BootSectGui - AutoIt3", $sPathBootSect, $sDriveSelectionItems, $sDriveSelectionFirst, $sBootCode, $sp ; GUI + ID Local $hBootSectGuiMain, $msg, $iSingleDrive, $iAllDrives, $iSYSDrive, $iNT60, $iNT52, $iMBRYesNo, $iForceYesNo, $iDriveSelection, $iBtnWrite, $iQuit If FileExists(@WorkingDir & "\bootsect.exe") Then $sPathBootSect = @WorkingDir & "\bootsect.exe" ElseIf FileExists(@ScriptDir & "\bootsect.exe") Then $sPathBootSect = @ScriptDir & "\bootsect.exe" ElseIf FileExists(@SystemDir & "\bootsect.exe") Then $sPathBootSect = @SystemDir & "\bootsect.exe" ElseIf FileExists(@WindowsDir & "\bootsect.exe") Then $sPathBootSect = @WindowsDir & "\bootsect.exe" Else MsgBox(16 + 262144, $Title, "The necessary 'BootSect.exe' file not found!" & @CRLF & @CRLF & "The program will end now!") Exit EndIf ;Main Menu $hBootSectGuiMain = GUICreate($Title, 525, 175) Local $GuiX = 18, $GuiY = 20 ; Group Drive(s) GUICtrlCreateGroup("Write master boot code into", $GuiX, $GuiY, 189, 130) $iAllDrives = GUICtrlCreateRadio("All Drives", $GuiX + 15, $GuiY + 20, 80) $iSingleDrive = GUICtrlCreateRadio("Single Drive:", $GuiX + 15, $GuiY + 45, 80) GUICtrlSetState(-1, $GUI_CHECKED) ; ================================= $sp = Chr(1) Opt("GUIDataSeparatorChar", $sp) $sDriveSelectionItems = _GetDrv() If Not $sDriveSelectionItems Then ; An error occurred when retrieving the drives. MsgBox(4096, $Title, "Error on querying drives" & @CRLF & @CRLF & "The program will end now!") Exit EndIf $sDriveSelectionFirst = StringRegExp($sDriveSelectionItems, '(?:\A|\001)([C-Z]: Fixed.*?)(?=\001)', 1) If @error Then $sDriveSelectionFirst = StringLeft($sDriveSelectionItems, StringInStr($sDriveSelectionItems & $sp, $sp) - 1) Else $sDriveSelectionFirst = $sDriveSelectionFirst[0] EndIf $iDriveSelection = GUICtrlCreateCombo("", $GuiX + 15, $GuiY + 70, 160, 25, $WS_VSCROLL + $CBS_DROPDOWNLIST) GUICtrlSetFont(-1, -1, -1, 0, "Courier New") GUICtrlSendMsg(-1, 0x160, 370, 0) GUICtrlSetData(-1, $sDriveSelectionItems, $sDriveSelectionFirst) ; ================================= $iSYSDrive = GUICtrlCreateRadio("System Drive", $GuiX + 15, $GuiY + 95, 80) GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group $GuiX += 205 ; Group Windows version GUICtrlCreateGroup("Select master boot code version", $GuiX, $GuiY, 185, 80) $iNT60 = GUICtrlCreateRadio("Windows Vista/7/8 ""/NT60""", $GuiX + 15, $GuiY + 20, 160) GUICtrlSetState(-1, $GUI_CHECKED) $iNT52 = GUICtrlCreateRadio("Windows XP ""/NT52""", $GuiX + 15, $GuiY + 45, 130) GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group $GuiX += 200 ; Group Master Boot Record GUICtrlCreateGroup("Options", $GuiX, $GuiY, 85, 80) $iMBRYesNo = GUICtrlCreateCheckbox("MBR", $GuiX + 15, $GuiY + 20, 60) GUICtrlSetState(-1, $GUI_CHECKED) $iForceYesNo = GUICtrlCreateCheckbox("Force", $GuiX + 15, $GuiY + 45, 60) GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group ; Group Button Local $ButtonX = 18 + 205 + 17, $ButtonY = $GuiY + 95 $iBtnWrite = GUICtrlCreateButton("Write master boot code", $ButtonX, $ButtonY, 150, 40) $iQuit = GUICtrlCreateButton("Quit", $ButtonX + 183, $ButtonY, 85, 40) GUICtrlSetState(-1, $GUI_FOCUS) ; the focus is on this button GUISetState() ; Run the GUI until the dialog is closed While 1 Switch GUIGetMsg() Case $iBtnWrite If GUICtrlRead($iNT60) = $GUI_CHECKED Then $sBootCode = "/NT60" ElseIf GUICtrlRead($iNT52) = $GUI_CHECKED Then $sBootCode = "/NT52" EndIf If GUICtrlRead($iSingleDrive) = $GUI_CHECKED Then BootSectLog(StringLeft(GUICtrlRead($iDriveSelection), 2)) ElseIf GUICtrlRead($iAllDrives) = $GUI_CHECKED Then BootSectLog("All") Else BootSectLog("SYS") EndIf Case $iSingleDrive GUICtrlSetState($iDriveSelection, $GUI_ENABLE) Case $iAllDrives, $iSYSDrive GUICtrlSetState($iDriveSelection, $GUI_DISABLE) Case $GUI_EVENT_CLOSE, $iQuit Exit EndSwitch WEnd Func BootSectLog($sBootSectDrive) Local $hBootSectGuiLog, $iPID, $sBootSectInProgress, $iBootSectLog, $sLine, $iWidth = 530, $iHeight = 330, $iClose, $sMBR, $sForce If GUICtrlRead($iMBRYesNo) = $GUI_CHECKED Then $sMBR = " /mbr" If GUICtrlRead($iForceYesNo) = $GUI_CHECKED Then $sForce = " /force" $iPID = Run(@ComSpec & ' /c "' & $sPathBootSect & '" ' & $sBootCode & " " & $sBootSectDrive & $sMBR & $sForce, @ScriptDir, @SW_HIDE, $STDOUT_CHILD) $sBootSectInProgress = "Executing:" & @CRLF & " Bootsect " & $sBootCode & " " & $sBootSectDrive & $sMBR & $sForce & @CRLF & @CRLF & "--------------------------------------------------------------------------------" GUISetState(@SW_DISABLE, $hBootSectGuiMain) $hBootSectGuiLog = GUICreate("BootSect Log", $iWidth, $iHeight, -1, -1, $WS_CAPTION + $WS_SYSMENU + $WS_POPUP, -1, $hBootSectGuiMain) $iBootSectLog = GUICtrlCreateEdit($sBootSectInProgress, 2, 2, $iWidth, $iHeight - 60) $iClose = GUICtrlCreateButton("Close", $iWidth / 2 - 148, $iHeight - 38, 295, 30) GUICtrlSetState(-1, $GUI_DISABLE) ; Disable "Close" button GUISetState(@SW_SHOW, $hBootSectGuiLog) _GUICtrlEdit_AppendText($iBootSectLog, @CRLF) ; Add space While 1 $sLine = StdoutRead($iPID) If @error Then ExitLoop If $sLine Then _GUICtrlEdit_AppendText($iBootSectLog, @CRLF & $sLine) WEnd _GUICtrlEdit_AppendText($iBootSectLog, @CRLF & "--------------------------------------------------------------------------------" & @CRLF & @CRLF & "Bootsect has terminated itself") GUICtrlSetState($iClose, $GUI_ENABLE) ; Enable "Close" button While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Or $msg = $iClose Then GUISetState(@SW_ENABLE, $hBootSectGuiMain) GUIDelete($hBootSectGuiLog) ExitLoop EndIf WEnd EndFunc ;==>BootSectLog Func _GetDrv() Local $sInfo = _ComboListDrive('Fixed') $sInfo &= _ComboListDrive('Removable') Return StringTrimLeft($sInfo, 1) EndFunc ;==>_GetDrv Func _ComboListDrive($Type) ; coded by AZJIO (2013.01.26) Local $aDrive = DriveGetDrive($Type), $list = '', $sString, $sLabel If @error Then Return '' If $Type = 'Removable' Then $Type = 'Rem' For $i = 1 To $aDrive[0] If $aDrive[$i] = 'A:' Then ContinueLoop $sLabel = DriveGetLabel($aDrive[$i]) If StringLen($sLabel) > 15 Then $sLabel = StringLeft($sLabel, 12) & '...' $sString = StringFormat("%-2s %-5s %-15s %-5s ", StringUpper($aDrive[$i]), $Type, $sLabel, _ DriveGetFileSystem($aDrive[$i])) & _GetSize(DriveSpaceTotal($aDrive[$i])) & ' Gb' $list &= $sp & $sString Next Return $list EndFunc ;==>_ComboListDrive Func _GetSize($s) ; coded by AZJIO $s = StringFormat('%.03f', $s / 1024) If StringLen($s) > 7 Then $s = StringRegExpReplace(StringTrimRight($s, 4), '(\A\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))', '\1 ') & StringRight($s, 4) Return StringFormat('%9s', $s) ; 9 ???????? EndFunc ;==>_GetSize - - - - -
      Edit 1: Corrected mistype in topic title, updated code with JFX recommendation and updated BootSectGui_x64 - Main.png with the new code. Version 1.1
      Edit 2: Added /mbr (by default). Corrected the line to execute bootsect.exe using the variable $BootSect. Version 1.1.1
      Edit 3: Added /force. Corrected a bug when not founding boosect.exe. Added SYS (system drive) in the list. Updated BootSectGui_x64 - Main.png, BootSectGui_x64 - Log.png and exe files. Version 1.2
      Edit 4: Added improvement by AZJIO and updated files. Version 1.3
      Edit 5: Little update of code added version 1.2.1 with improvement of AZJIO and a simple list of drives.
      BootSectGui_x64.7z