Jump to content
Bilgus

Sandisk Connect 16G Wireless Thumb Drive Image Extraction

Recommended Posts

Bilgus

I made this script in an attempt to change the Default page on a $20 Sandisk 16Gb Wireless Thumbdrive

While I was able to execute my own code I couldn't find a way to change the actual device address

What does it do?

When you take the thumb drive apart it has a sdcard that contains the firmware on a hidden partition you can access this partition from a separate card readerĀ and extract the files with this script

you then edit the files and copy them back to the device with a hex editor

#include <FileConstants.au3>
#include <MsgBoxConstants.au3>
#include <WinAPIFiles.au3>
#include <AutoItConstants.au3>
#include <String.au3>
#include <Array.au3> ; Required for _ArrayDisplay() only.
#include <File.au3> ;FileWriteLog


Local $sFileOpenDialog = FileOpenDialog("Choose Firmware File", _
        @ScriptDir, "All (*)|Disk Images (*.img)|Firmware (*.df3)", 3)

Local $sLogPath = $sFileOpenDialog & ".log"
Local $sWritePath = $sFileOpenDialog & "_Files\"
Local $sMessage = ""
Local Const $sSplashTitle = "Extract Connect Files"
Global $iStartPos = 0

While ($iStartPos > -1)
    $iStartPos = ExtractConnectFiles($sFileOpenDialog, $sLogPath, $sWritePath, $iStartPos)
WEnd


Func _StringEqualSplit($sString, $iNumChars)
    If (Not IsString($sString)) Or $sString = "" Then Return SetError(1, 0, 0)
    If (Not IsInt($iNumChars)) Or $iNumChars < 1 Then Return SetError(2, 0, 0)
    Return StringRegExp($sString, "(?s).{1," & $iNumChars & "}", 3)
EndFunc   ;==>_StringEqualSplit


Func _Exit($hLogFile, $hBinaryFileOpen)
    $iStartPos = -1
    Sleep(3000)
    FileClose($hLogFile)
    FileClose($hBinaryFileOpen)
    Exit
EndFunc   ;==>_Exit


Func FindStorageHeader($sFilePath, $iFileSz, $iStartPos) ;FF FF FF FF 00 00 [00 00 SZ BY] .. [00 00 00 01]
    Local $i, $hBinaryFileOpen = FileOpen($sFilePath, 0 + 16)
    Local $sHexSearch = "0xFFFFFFFF0000"
    Local $iSearchSz = Int((StringLen($sHexSearch) - 2) / 2)
    Local $iFileSzKb = Int($iFileSz / 1024)
    Local $iRetPos = -1
    Local $iFileHeaderLen = 0
    If $hBinaryFileOpen = -1 Then
        MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading the file.")
        Return -1
    EndIf
    If ($iFileSzKb > 17000) Then ; Probably a diskimage let user decide where to search
        $iStartPos = InputBox("Large File, Search from a different offset?", "Enter the offset you would like to search from [0 -" _
                 & $iFileSz - $iSearchSz - 1 & "]", $iStartPos, Default, -1, -1, Default, Default, 30)
    EndIf
    For $i = $iStartPos To $iFileSz - $iSearchSz - 1
        $iFileProgress = Int(($i + 1) / 1024)
        If ($iFileProgress = ($i + 1) / 1024) Then
            If (0 = ControlSetText($sSplashTitle, "", "Static1", $sMessage & _
                    "Searching for Storage Header... (" & $iFileProgress & " / " & $iFileSzKb & ") ")) Then ExitLoop

        EndIf
        FileSetPos($hBinaryFileOpen, $i, 0)
        $Data = FileRead($hBinaryFileOpen, $iSearchSz) ; ;FF FF FF FF 00 00
        If ($Data = $sHexSearch) Then
            $iFileHeaderLen = Dec(ExtractHexBytes($hBinaryFileOpen, $i + 4, 4), 1) ; [00 00 SZ BY] extract len in hex convert to 32 bit decimal
            $iRetPos = $i
            If (1 = Dec(ExtractHexBytes($hBinaryFileOpen, $i + 8, 4), 1)) Then ExitLoop ;.. [00 00 00 01]
        EndIf
    Next
    FileClose($hBinaryFileOpen)
    Return $iRetPos
EndFunc   ;==>FindStorageHeader


Func ExtractHexBytes($hBinaryFileOpen, $iStart, $iBytes)
    Local $iOldPos = FileGetPos($hBinaryFileOpen)
    If @error Or $hBinaryFileOpen = -1 Then
        MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading the file.")
        Return ""
    EndIf

    FileSetPos($hBinaryFileOpen, $iStart, 0) ;Offset from beginning
    Global $Data = FileRead($hBinaryFileOpen, $iBytes)
    FileSetPos($hBinaryFileOpen, $iOldPos, 0) ;Restore original position
    Return StringTrimLeft(String($Data), 2) ;Remove 0x from beginning
EndFunc   ;==>ExtractHexBytes


Func FileTypeExtension($iFileType)
    Local Const $aFileExt[12][2] = [[0, ".UNK"], [1, ".UNK"], _
            [14, ".swf"], [15, ".zip"], [25, ".gif"], [27, ".png"], _
            [28, ".xml"], [33, ".css"], [35, ".html"], [36, ".JS"], [37, ".txt"]]

    Local $i = 0
    Local $sExt = $aFileExt[0][1]
    For $i = 0 To UBound($aFileExt) - 1
        If ($aFileExt[$i][0] = $iFileType) Then
            Local $sExt = $aFileExt[$i][1]
            ExitLoop
        EndIf
    Next
    Return $sExt
EndFunc   ;==>FileTypeExtension


Func ExtractConnectFiles($sFilePath, $sLogPath, $sWritePath, $iStartPos)
    Local $hLogFile = FileOpen($sLogPath, 1)
    Local $iFileSz = FileGetSize($sFilePath)
    Local $i = 0, $j = 0
    Local $sLogMsg = "Extract Connect Files Started" & @CRLF & "Sz: " & $iFileSz & " bytes, Path: " & $sFilePath & @CRLF

    $sMessage = $sLogMsg
    SplashTextOn($sSplashTitle, $sMessage & _
            "Searching for Storage Header...", -1, 200, -1, 18, _
            BitOR($DLG_TEXTLEFT, $DLG_NOTONTOP, $DLG_MOVEABLE), "", 10)
    Sleep(1000)
    _FileWriteLog($hLogFile, $sLogMsg)
    $iStartPos = FindStorageHeader($sFilePath, $iFileSz, $iStartPos)
    If ($iStartPos > -1) Then
        $sLogMsg = "Storage Header Found @ " & String(Hex($iStartPos))
        $sMessage = $sMessage & $sLogMsg & @CRLF
        _FileWriteLog($hLogFile, $sLogMsg)
    Else
        $sLogMsg = "!Error! Storage Header Not Found!"
        _FileWriteLog($hLogFile, $sLogMsg)
        ControlSetText($sSplashTitle, "", "Static1", $sMessage & @CRLF & $sLogMsg & @CRLF & "Exiting...")
        _Exit($hLogFile, -1)
    EndIf
    ControlSetText($sSplashTitle, "", "Static1", $sMessage)
    Local $hBinaryFileOpen = FileOpen($sFilePath, 0 + 16)
    If $hBinaryFileOpen = -1 Then
        MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading the file.")
        _Exit($hLogFile, -1)
    EndIf
    Local $iFileHeaderLen = Dec(ExtractHexBytes($hBinaryFileOpen, $iStartPos + 4, 4), 1) ;extract len in hex convert to 32 bit decimal
    If ($iFileHeaderLen > 600 Or $iFileHeaderLen < 200) Then
        Local $iCancelTryContinue = MsgBox(16 + 6, "Error", _
                "Header Length is out of range continue to force or try again to find a new header", 30)

        If ($iCancelTryContinue = 2) Then
            _Exit($hLogFile, -1)
        ElseIf ($iCancelTryContinue = 10 Or $iCancelTryContinue = -1) Then ;tryagain or timeout
            Return $iStartPos + 1
        EndIf
    EndIf
    Local $sFileHeader = ExtractHexBytes($hBinaryFileOpen, $iStartPos + 8, $iFileHeaderLen)
    $sLogMsg = "FileHeader Sz: " & $iFileHeaderLen & " bytes" & @CRLF & "Data:[" & $sFileHeader & "]"
    $sMessage = $sMessage & "File Header Found! Sz: " & $iFileHeaderLen & " bytes" & @CRLF
    ControlSetText($sSplashTitle, "", "Static1", $sMessage)
    _FileWriteLog($hLogFile, $sLogMsg)
    Local $iElemsPer = 3 ; Each file has [Index, offset, Type]
    Local $aS = _StringEqualSplit($sFileHeader, 8)
    If IsArray($aS) Then
        Local $iFileCount = Int(UBound($aS) / $iElemsPer)
        Local $aFileData[$iFileCount][4] ;We will store the file data as [FileIndex, FileType, FileOffset, SzBytes]
        $j = 0 ;
        ;_ArrayDisplay($aS, "Raw File Header", Default, 32 + 64, Default, "", Default, 0xDDFFDD)
        For $i = 0 To UBound($aS) - 1 Step $iElemsPer
            $aFileData[$j][0] = Dec($aS[$i + 0])
            $aFileData[$j][1] = FileTypeExtension(Dec($aS[$i + 2]))
            $aFileData[$j][2] = $iStartPos + Dec($aS[$i + 1])
            Local $iFileHeaderOffset = Dec(ExtractHexBytes($hBinaryFileOpen, $aFileData[$j][2], 4), 1)
            If ($iFileHeaderOffset = $aFileData[$j][0]) Then ;check header at offset see if it matches
                $aFileData[$j][3] = Dec(ExtractHexBytes($hBinaryFileOpen, $aFileData[$j][2] + 4, 4), 1) ;extract len in hex convert to 32 bit decimal
            Else

                $aFileData[$j][3] = "BAD HEADER"
                Local $iCancelTryContinue = MsgBox(16 + 6, "Error", _
                        "File Has a bad Header continue or try again to find a new storage header", 30)

                If ($iCancelTryContinue = 2) Then
                    _Exit($hLogFile, $hBinaryFileOpen)
                ElseIf ($iCancelTryContinue = 10 Or $iCancelTryContinue = -1) Then ;tryagain or timeout
                    Return $iStartPos + 1
                EndIf

            EndIf
            $sLogMsg = "File Index: " & $aFileData[$j][0] & " File Type: " & _
                    $aFileData[$j][1] & " File Offset: 0x" & Hex($aFileData[$j][2], 8) & _
                    " File Size Bytes:" & $aFileData[$j][3]

            _FileWriteLog($hLogFile, $sLogMsg)
            $j = $j + 1
            If ($j > $iFileCount) Then
                MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading FileData")
            EndIf
        Next
        _ArrayDisplay($aFileData, $sSplashTitle & " Found", Default, 16 + 32 + 64, Default, _
                "Index |Type |Offset |Bytes ", 500, 0xDDFFDD)

        $sMessage = $sMessage & "Extracting Files: " & $sWritePath & @CRLF
        If (7 = MsgBox(4 + 32 + 256, "Extract Files?", "Press Yes to Extract files to" & @CRLF & $sWritePath)) Then
            _Exit($hLogFile, $hBinaryFileOpen)
        EndIf
        SplashTextOn($sSplashTitle, $sMessage, -1, 200, -1, 18, BitOR($DLG_TEXTLEFT, $DLG_NOTONTOP, $DLG_MOVEABLE), "", 10)

        For $i = 0 To $iFileCount - 1
            If ($aFileData[$i][3] <> "BAD HEADER") Then
                ControlSetText($sSplashTitle, "", "Static1", $sMessage & " (" & $i + 1 & "/" & $iFileCount & ") " & _
                        $aFileData[$i][0] & $aFileData[$i][1])

                FileSetPos($hBinaryFileOpen, ($aFileData[$i][2]) + 8, 0)
                Local $hBinaryFileWrite = FileOpen($sWritePath & $aFileData[$i][0] & $aFileData[$i][1], 2 + 8 + 16)
                If @error Or $hBinaryFileOpen = -1 Then
                    MsgBox($MB_SYSTEMMODAL, "", "An error occurred trying to write the file." & @CRLF & _
                            $sWritePath & $aFileData[$i][0] & $aFileData[$i][1])

                    ExitLoop
                EndIf
                FileWrite($hBinaryFileWrite, FileRead($hBinaryFileOpen, $aFileData[$i][3]))
                FileClose($hBinaryFileWrite)

            EndIf
        Next

    EndIf

    _Exit($hLogFile, $hBinaryFileOpen)
EndFunc   ;==>ExtractConnectFiles

My original FindingsĀ 

https://forums.hak5.org/topic/41479-sandisk-wireless-connect-16g-flash-drive/

Edited by Bilgus

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

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.