Jump to content

Help with binary


Recommended Posts

I have been working on an autoit patcher. You compare two executables, the old version, and the new version.

Once it gets the difference between the two, it then writes the byte differences to the old version to make it the new version. The only problem is that it seems that autoit doesn't have a native binary read or write method. It has been writing in binary, but it hasn't written any null values(Hexidecimal 00?). Everything else seems to get written ok, but it doesn't write the null values. I am not sure what i am doing wrong or if autoit can even do what i am trying to get it to do.

http://www.thekandieman.com/applications/P...er/download.php

There is the source and two executables that it compares and patches.

"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Link to comment
Share on other sites

  • Moderators

Figured it out TKC ... I'll either work up the entire interface later while your in school, or send you what I did, and you can take care of it.

2 functions 35 lines total ... :lmao:

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I think you SmOke_N. He helped me with it and was able to make a working version. Unfortunately it isn't very fast at patching large files and cannot create a portable database that is smaller than the file to be patched itself. Any help from any senior programmers would be most appreciated.

I can PM you my latest updates of my source code if you would like me to, simply PM me or reply to this thread.

Any help would be appreciated, whenever i write to file it seems to write a string of ASCII binary characters to the file instead of actual binary. :S

-The Kandie Man

Edited by The Kandie Man

"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Link to comment
Share on other sites

  • Moderators

I think you SmOke_N. He helped me with it and was able to make a working version. Unfortunately it isn't very fast at patching large files and cannot create a portable database that is smaller than the file to be patched itself. Any help from any senior programmers would be most appreciated.

I can PM you my latest updates of my source code if you would like me to, simply PM me or reply to this thread.

Any help would be appreciated, whenever i write to file it seems to write a string of ASCII binary characters to the file instead of actual binary. :S

-The Kandie Man

I tried to IM you, guess you are going torrent crazy again.

This is what I did to speed it up 10x's as fast. But, there's an issue in my logic, or I'm just not seeing something.

It reads the Old to be patched exe and the new exe and compares their binary. Writes the Chr Number / Chr / and remaining difference of chrs if the new file is greater than the old in String Length each to their seperate file.

Then it outputs a GUI with the function to patch the old exe on the end-users computer, using FileInstall to install the 3 files for this and outputs them to the pre-destined name and temp file and then reads them to an array.

I was initially, as you know, using StringLeft()/StringTrimLeft() for the changing of the file, but it proved for large changes to be quite tedious. It now reads the end-users exe into an array, and changes only the necessary items, this sped it up alot, and then it re-writes all the info back to a temp var, and then writes that temp var to a file and FileMoves to the old exe with the old exe name.

Anyone that uses this, should make a folder, put the .au3 of this in that folder, then make an OldExe SubFolder.. Put the OldExe in it, and a NewExe SubFolder and put the new exe in it.

If anyone wants to play with it feel free, I kind of gave up on it because the output was genrally more in size then just replacing the actual exe itself.

CODE
Global $hNewExe, $hOldExe, $aExeArray

$GUIMain = GUICreate("AutoPatchIt: AutoIt Exe Patch Creator", 355, 150)

GUICtrlCreateLabel("New Release:", 110, 10, 110, 22)

GUICtrlSetFont(-1, 8, 800, 0, "Verdana")

$B1 = GUICtrlCreateButton("www", 192, 2, 30, 25, 0)

GUICtrlSetFont(-1, 8, 800, 0, "Wingdings")

GUICtrlCreateLabel("Old Release:", 115, 60, 110, 22)

GUICtrlSetFont(-1, 8, 800, 0, "Verdana")

$B2 = GUICtrlCreateButton("www", 192, 52, 30, 25, 0)

GUICtrlSetFont(-1, 8, 800, 0, "Wingdings")

$B3 = GUICtrlCreateButton("Create Patch", 120, 115, 115, 25, 0)

GUICtrlSetFont(-1, 8, 800, 0, "Verdana")

$I1 = GUICtrlCreateEdit("", 10, 30, 340, 20, BitOR(0x0800, 0x0080))

$I2 = GUICtrlCreateEdit("", 10, 80, 340, 20, BitOR(0x0800, 0x0080))

GUISetState()

While 1

Switch GUIGetMsg()

Case - 3

Exit

Case $B1

$hNewExe = FileOpenDialog('New Release', @ScriptDir, 'Exe (*.exe)')

If Not @error Then

GUICtrlSetData($I1, '')

GUICtrlSetData($I1, $hNewExe)

EndIf

Case $B2

$hOldExe = FileOpenDialog('Old Release', @ScriptDir, 'Exe (*.exe)')

If Not @error Then

GUICtrlSetData($I2, '')

GUICtrlSetData($I2, $hOldExe)

EndIf

Case $B3

If $hOldExe <> $hNewExe Then

$aExeArray = _CompareExe2Exe($hNewExe, $hOldExe)

MsgBox(64, 'Info', 'Finished!' & @CR & _

'Your Patch .Au3 file is here: ' & @CR & _

_CreatePatchAu3($hOldExe, $aExeArray))

$hOldExe = ''

$hNewExe = ''

EndIf

EndSwitch

WEnd

Func _CompareExe2Exe($hNew, $hOld)

Local $sOld = String(FileRead($hOld)), $aOld = StringSplit($sOld, '')

Local $sNew = String(FileRead($hNew)), $aNew = StringSplit($sNew, '')

Local $iUBOld = UBound($aOld) - 1, $iUBNew = UBound($aNew) - 1, $iUBound = $iUBOld

If $iUBNew < $iUBOld Then $iUBound = $iUBNew

Local $aOutNC[$iUBound + 1][5], $iAdd = 1, $nNCC, $nXCC

ProgressOn("Comparing Both Exe's", "", "", -1, -1, 18)

For $iCC = 1 To $iUBound Step 5

If $aNew[$iCC] <> $aOld[$iCC] Then

$iAdd += 1

$aOutNC[$iAdd - 1][0] = $iCC

$aOutNC[$iAdd - 1][1] = $aNew[$iCC]

EndIf

If $iCC < $iUBound - 1 And $aNew[$iCC + 1] <> $aOld[$iCC + 1] Then

$iAdd += 1

$aOutNC[$iAdd - 1][0] = $iCC

$aOutNC[$iAdd - 1][1] = $aNew[$iCC]

EndIf

If $iCC < $iUBound - 2 And $aNew[$iCC + 2] <> $aOld[$iCC + 2] Then

$iAdd += 1

$aOutNC[$iAdd - 1][0] = $iCC

$aOutNC[$iAdd - 1][1] = $aNew[$iCC]

EndIf

If $iCC < $iUBound - 3 And $aNew[$iCC + 3] <> $aOld[$iCC + 3] Then

$iAdd += 1

$aOutNC[$iAdd - 1][0] = $iCC

$aOutNC[$iAdd - 1][1] = $aNew[$iCC]

EndIf

If $iCC < $iUBound - 4 And $aNew[$iCC + 4] <> $aOld[$iCC + 4] Then

$iAdd += 1

$aOutNC[$iAdd - 1][0] = $iCC

$aOutNC[$iAdd - 1][1] = $aNew[$iCC]

EndIf

$nNCC = (($iCC + 4) / $iUBound) * 100

If Int($nNCC) <> $nXCC Then

ProgressSet($nNCC , (100 - Int($nNCC)) & ' % To Go', Int($nNCC) & '% Finshed Comparing')

$nXCC = Int($nNCC)

EndIf

Next

ProgressOff()

ReDim $aOutNC[$iAdd][5]

$aOutNC[0][2] = ''

If $iUBNew > $iUBOld Then

$aOutNC[0][2] = StringRight($sNew, $iUBNew - $iUBOld)

EndIf

$aOutNC[0][3] = $iUBNew

$aOutNC[0][4] = $iUBOld

Return $aOutNC

EndFunc ;==>_CompareExe2Exe

Func _CreatePatchAu3($hExe, $aOutNC)

Local $hF1 = _GetTempFileName(), $hF2 = _GetTempFileName(), $hF3 = _GetTempFileName()

Local $hOutFile = StringLeft(@ScriptFullPath, StringInStr(@ScriptFullPath, '.', 0, -1) - 1) & '_Patcher.au3'

Local $hTempNum = @ScriptDir & '\TempNum.tmp', $hTempChr = @ScriptDir & '\TempChr.tmp'

Local $hTempEx = @ScriptDir & '\TempExt.tmp', $sWNum, $sWChr

FileClose(FileOpen($hTempNum, 2))

FileClose(FileOpen($hTempChr, 2))

FileClose(FileOpen($hTempEx, 2))

FileClose(FileOpen($hOutFile, 2))

Local $sWrite = 'Global $hOldExe' & @CRLF & _

'FileInstall("' & $hTempNum & '", "' & $hF1 & '")' & @CRLF & _

'FileInstall("' & $hTempChr & '", "' & $hF2 & '")' & @CRLF & _

'FileInstall("' & $hTempEx & '", "' & $hF3 & '")' & @CRLF & _

'$GUIMain = GUICreate("", 355, 95);Fill in a title' & @CRLF & _

'GUICtrlCreateLabel("", 85, 8, 110, 17);Fill in the label' & @CRLF & _

'GUICtrlSetFont(-1, 8, 800, 0, "Verdana")' & @CRLF & _

'$B1 = GUICtrlCreateButton("www", 192, 7, 27, 17, 0)' & @CRLF & _

'GUICtrlSetFont(-1, 8, 800, 0, "Wingdings")' & @CRLF & _

'$B2 = GUICtrlCreateButton("Patch It", 121, 60, 113, 25, 0)' & @CRLF & _

'GUICtrlSetFont(-1, 8, 800, 0, "Verdana")' & @CRLF & _

'$I1 = GUICtrlCreateEdit("", 10, 28, 337, 21, BitOR(0x0800, 0x0080))' & @CRLF & _

'GUISetState()' & @CRLF & _

'While 1' & @CRLF & _

' Switch GUIGetMsg()' & @CRLF & _

' Case -3' & @CRLF & _

' Exit' & @CRLF & _

' Case $B1' & @CRLF & _

' $hOldExe = FileOpenDialog("Find Exe", @WorkingDir, "Exe (*.exe)")' & @CRLF & _

' If Not @error Then' & @CRLF & _

' GUICtrlSetData($I1, "")' & @CRLF & _

' GUICtrlSetData($I1, $hOldExe)' & @CRLF & _

' EndIf' & @CRLF & _

' Case $B2' & @CRLF & _

' _WritePatch($hOldExe)' & @CRLF & _

' EndSwitch' & @CRLF & _

'WEnd' & @CRLF & _

'Func _WritePatch($hExe)' & @CRLF & _

' Local $iNewTotal = ' & $aOutNC[0][3] & ', ' & '$iOldTotal = ' & $aOutNC[0][4] & @CRLF & _

' Local $sExe = String(FileRead($hExe)), $sTemp = ""' & @CRLF & _

' If $iNewTotal < $iOldTotal Then $sExe = StringTrimRight($sExe, $iOldTotal - $iNewTotal)' & @CRLF & _

' Local $nNum = StringSplit(FileRead("' & $hF1 & '"), Chr(1))' & @CRLF & _

' Local $sChr = StringSplit(FileRead("' & $hF2 & '"), Chr(1))' & @CRLF & _

' $sExe = StringSplit($sExe, "")' & @CRLF & _

' Local $nNCC, $nXCC, $iUBound = UBound($nNum) - 1, $iUBound2 = UBound($sExe) - 1' & @CRLF & _

' ProgressOn("Setting Enviroment...", "", "", -1, -1, 16)' & @CRLF & _

' For $xCC = 1 To $iUBound Step 5' & @CRLF & _

' $sExe[$nNum[$xCC]] = $sChr[$xCC]' & @CRLF & _

' If $xCC < $iUBound - 1 Then $sExe[$nNum[$xCC + 1]] = $sChr[$xCC + 1]' & @CRLF & _

' If $xCC < $iUBound - 2 Then $sExe[$nNum[$xCC + 2]] = $sChr[$xCC + 2]' & @CRLF & _

' If $xCC < $iUBound - 3 Then $sExe[$nNum[$xCC + 3]] = $sChr[$xCC + 3]' & @CRLF & _

' If $xCC < $iUBound - 4 Then $sExe[$nNum[$xCC + 4]] = $sChr[$xCC + 4]' & @CRLF & _

' $nNCC = (($xCC + 4) / $iUBound) * 100' & @CRLF & _

' If Int($nNCC) <> $nXCC Then' & @CRLF & _

' ProgressSet($nNCC , (100 - Int($nNCC)) & " % To Go", Int($nNCC) & "% Finshed Patching")' & @CRLF & _

' $nXCC = Int($nNCC)' & @CRLF & _

' EndIf' & @CRLF & _

' Next' & @CRLF & _

' ProgressOff()' & @CRLF & _

' ProgressOn("Patching...", "", "", -1, -1, 16)' & @CRLF & _

' For $iCC = 1 To $iUBound2 Step 5' & @CRLF & _

' $sTemp &= $sExe[$iCC]' & @CRLF & _

' If $iCC < $iUBound2 - 1 Then $sTemp &= $sExe[$iCC + 1]' & @CRLF & _

' If $iCC < $iUBound2 - 2 Then $sTemp &= $sExe[$iCC + 2]' & @CRLF & _

' If $iCC < $iUBound2 - 3 Then $sTemp &= $sExe[$iCC + 3]' & @CRLF & _

' If $iCC < $iUBound2 - 4 Then $sTemp &= $sExe[$iCC + 4]' & @CRLF & _

' $nNCC = (($iCC + 4) / $iUBound2) * 100' & @CRLF & _

' If Int($nNCC) <> $nXCC Then' & @CRLF & _

' ProgressSet($nNCC , (100 - Int($nNCC)) & " % To Go", Int($nNCC) & "% Finshed Patching")' & @CRLF & _

' $nXCC = Int($nNCC)' & @CRLF & _

' EndIf' & @CRLF & _

' Next' & @CRLF & _

' ProgressOff()' & @CRLF & _

' $sTemp &= FileRead("' & $hF3 & '")' & @CRLF & _

' $hNewOut = StringLeft($hExe, StringInStr($hExe, ".", 0, -1)) & ".patched"' & @CRLF & _

' FileClose(FileOpen($hNewOut, 2))' & @CRLF & _

' FileWrite($hNewOut, BinaryString($sTemp))' & @CRLF & _

' FileMove($hNewOut, $hExe, 1)' & @CRLF & _

' FileDelete("' & $hF1 & '")' & @CRLF & _

' FileDelete("' & $hF2 & '")' & @CRLF & _

' FileDelete("' & $hF3 & '")' & @CRLF & _

' Return 1' & @CRLF & _

'EndFunc'

For $xCC = 1 To UBound($aOutNC) - 1

$sWNum &= $aOutNC[$xCC][0] & Chr(1)

$sWChr &= $aOutNC[$xCC][1] & Chr(1)

Next

$sWNum = StringTrimRight($sWNum, 1)

$sWChr = StringTrimRight($sWChr, 1)

FileWrite($hTempNum, $sWNum)

FileWrite($hTempChr, $sWChr)

FileWrite($hTempEx, $aOutNC[0][2])

FileWrite($hOutFile, $sWrite)

Return $hOutFile

EndFunc ;==>_CreatePatchAu3

Func _GetTempFileName()

Local $oFSO = ObjCreate("Scripting.FileSystemObject"), $sTFolder

$sTFolder = $oFSO.GetSpecialFolder (2)

Return @TempDir & "\" & $oFSO.GetTempName

EndFunc ;==>_GetTempFileName

P.S.

Before anyone asks why I didn't just transfer all the info over into array form, I originally did that, but the file was 3 x's as huge as the file I wanted to patch.

Since this needs the autoit exe to be passed with it to interpret, this didn't / doesn't seem to be a good approach with all the free patch programs out there (I tried a few today), they seem to be MUCH faster for obvious reasons anyway.

But it was fun all the same, maybe someone can pick up where I left off.

Edit:

Changed to codebox

Edit2:

Now that I look at as a public post... maybe it would have been smarter to go through like 1000 chrs at a time, and Just changed that.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Allright, i got it to work, but not. The problem is that i get it to output in binary, but for some reason every single null character (Hex 00) is gone. I don't know why the null character is missing. Do the string functions removed null characters. Particularly StringSplit?

"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Link to comment
Share on other sites

Yeah, i am using it to create a char[] array like in c++. It works fine except for the fact that it seems to want to truncate all null characters. I am missing all 6,257 occurances of null characters in my final output exe file.

EDIT

I am looking and i can't find any other efficient function for converting a string into a char array. Anyone here know of an efficient way to convert a string of binary to a char[] array where each element has only one byte of data?

Edited by The Kandie Man

"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Link to comment
Share on other sites

  • Moderators

This came out much more realistic.

Global $hNewExe, $hOldExe, $aExeArray
$GUIMain = GUICreate("AutoPatchIt:  AutoIt Exe Patch Creator", 355, 150)
GUICtrlCreateLabel("New Release:", 110, 10, 110, 22)
GUICtrlSetFont(-1, 8, 800, 0, "Verdana")
$B1 = GUICtrlCreateButton("www", 192, 2, 30, 25, 0)
GUICtrlSetFont(-1, 8, 800, 0, "Wingdings")
GUICtrlCreateLabel("Old Release:", 115, 60, 110, 22)
GUICtrlSetFont(-1, 8, 800, 0, "Verdana")
$B2 = GUICtrlCreateButton("www", 192, 52, 30, 25, 0)
GUICtrlSetFont(-1, 8, 800, 0, "Wingdings")
$B3 = GUICtrlCreateButton("Create Patch", 120, 115, 115, 25, 0)
GUICtrlSetFont(-1, 8, 800, 0, "Verdana")
$I1 = GUICtrlCreateEdit("", 10, 30, 340, 20, BitOR(0x0800, 0x0080))
$I2 = GUICtrlCreateEdit("", 10, 80, 340, 20, BitOR(0x0800, 0x0080))
GUISetState()
While 1
    Switch GUIGetMsg()
        Case - 3
            Exit
        Case $B1
            $hNewExe = FileOpenDialog('New Release', @ScriptDir, 'Exe (*.exe)')
            If Not @error Then
                GUICtrlSetData($I1, '')
                GUICtrlSetData($I1, $hNewExe)
            EndIf
        Case $B2
            $hOldExe = FileOpenDialog('Old Release', @ScriptDir, 'Exe (*.exe)')
            If Not @error Then
                GUICtrlSetData($I2, '')
                GUICtrlSetData($I2, $hOldExe)
            EndIf
        Case $B3
            If $hOldExe <> $hNewExe Then
                $aExeArray = _CompareExe2Exe($hNewExe, $hOldExe)
                MsgBox(64, 'Info', 'Finished!' & @CR & _
                        'Your Patch .Au3 file is here: ' & @CR & _
                        _CreatePatchAu3($hOldExe, $aExeArray))
                $hOldExe = ''
                $hNewExe = ''
            EndIf
    EndSwitch
WEnd
Func _CompareExe2Exe($hNew, $hOld)
    Local $sOld = FileRead($hOld)
    Local $sNew = FileRead($hNew)
    Local $nNewLen = StringLen($sNew), $nOldLen = StringLen($sOld)
    Local $nUBLen = Int($nNewLen) / 2050
    Local $aOutNC[$nUBLen + 1][4], $iAdd = 1, $nNCC, $nXCC
    ProgressOn("Comparing Both Exe's", "", "", -1, -1, 18)
    For $iCC = 1 To $nNewLen Step 2050
        $sMidNew = StringMid($sNew, $iCC, 2050)
        $sMidOld = StringMid($sOld, $iCC, 2050)
        If $sMidNew <> $sMidOld Then
            $iAdd += 1
            $aOutNC[$iAdd - 1][0] = $iCC
            $aOutNC[$iAdd - 1][1] = $sMidNew
        EndIf
        $nNCC = ($iCC / $nNewLen) * 100
        If Int($nNCC) <> $nXCC Then
            ProgressSet($nNCC , (100 - Int($nNCC))  & " % To Go", Int($nNCC) & "% Done Comparing.")
            $nXCC = Int($nNCC)
        EndIf
    Next
    ProgressOff()
    ReDim $aOutNC[$iAdd][4]
    $aOutNC[0][2] = $nNewLen
    $aOutNC[0][3] = $nOldLen
    Return $aOutNC
EndFunc   ;==>_CompareExe2Exe
Func _CreatePatchAu3($hExe, $aOutNC)
    Local $hF1 = _GetTempFileName(), $hF2 = _GetTempFileName()
    Local $hOutFile = StringLeft(@ScriptFullPath, StringInStr(@ScriptFullPath, '.', 0, -1) - 1) & '_Patcher.au3'
    Local $hTempNum = @ScriptDir & '\TempNum.tmp', $hTempChr = @ScriptDir & '\TempChr.tmp', $sWNum, $sWChr
    FileClose(FileOpen($hTempNum, 2))
    FileClose(FileOpen($hTempChr, 2))
    FileClose(FileOpen($hOutFile, 2))
    Local $sWrite = 'Global $hOldExe' & @CRLF & _
            'FileInstall("' & $hTempNum & '", "' & $hF1 & '")' & @CRLF & _
            'FileInstall("' & $hTempChr & '", "' & $hF2 & '")' & @CRLF & _
            '$GUIMain = GUICreate("", 355, 95);Fill in a title' & @CRLF & _
            'GUICtrlCreateLabel("", 85, 8, 110, 17);Fill in the label' & @CRLF & _
            'GUICtrlSetFont(-1, 8, 800, 0, "Verdana")' & @CRLF & _
            '$B1 = GUICtrlCreateButton("www", 192, 7, 27, 17, 0)' & @CRLF & _
            'GUICtrlSetFont(-1, 8, 800, 0, "Wingdings")' & @CRLF & _
            '$B2 = GUICtrlCreateButton("Patch It", 121, 60, 113, 25, 0)' & @CRLF & _
            'GUICtrlSetFont(-1, 8, 800, 0, "Verdana")' & @CRLF & _
            '$I1 = GUICtrlCreateEdit("", 10, 28, 337, 21, BitOR(0x0800, 0x0080))' & @CRLF & _
            'GUISetState()' & @CRLF & _
            'While 1' & @CRLF & _
            '    Switch GUIGetMsg()' & @CRLF & _
            '        Case -3' & @CRLF & _
            '            Exit' & @CRLF & _
            '        Case $B1' & @CRLF & _
            '            $hOldExe = FileOpenDialog("Find Exe", @WorkingDir, "Exe (*.exe)")' & @CRLF & _
            '            If Not @error Then' & @CRLF & _
            '                GUICtrlSetData($I1, "")' & @CRLF & _
            '                GUICtrlSetData($I1, $hOldExe)' & @CRLF & _
            '            EndIf' & @CRLF & _
            '        Case $B2' & @CRLF & _
            '            _WritePatch($hOldExe)' & @CRLF & _
            '    EndSwitch' & @CRLF & _
            'WEnd' & @CRLF & _
            'Func _WritePatch($hExe)' & @CRLF & _
            '    Local $iNewTotal = ' & $aOutNC[0][2] & ', ' & '$iOldTotal = ' & $aOutNC[0][3] & @CRLF & _
            '    Local $sExe = FileRead($hExe), $sTemp = $sExe' & @CRLF & _
            '    If $iNewTotal < $iOldTotal Then $sExe = StringTrimRight($sExe, $iOldTotal - $iNewTotal)' & @CRLF & _
            '    Local $nNum = StringSplit(FileRead("' & $hF1 & '"), Chr(1))' & @CRLF & _
            '    Local $sChr = StringSplit(FileRead("' & $hF2 & '"), Chr(1)&Chr(1)&Chr(1), 1)' & @CRLF & _
            '    Local $nNCC, $nXCC, $iUBound = UBound($nNum) - 1' & @CRLF & _
            '    ProgressOn("Patching...", "", "", -1, -1, 16)' & @CRLF & _
            '    For $xCC = 1 To $iUBound' & @CRLF & _
            '       $sTemp = StringLeft($sExe, $nNum[$xCC] - 1) & $sChr[$xCC] & StringTrimLeft($sExe, $nNum[$xCC] + 2049)' & @CRLF & _
            '       $sExe = $sTemp' & @CRLF & _
            '        $nNCC = ($xCC / $iUBound) * 100' & @CRLF & _
            '        If Int($nNCC) <> $nXCC Then' & @CRLF & _
            '            ProgressSet($nNCC , (100 - Int($nNCC))  & " % To Go", Int($nNCC) & "% Finshed Patching")' & @CRLF & _
            '            $nXCC = Int($nNCC)' & @CRLF & _
            '        EndIf' & @CRLF & _
            '    Next' & @CRLF & _
            '    ProgressOff()' & @CRLF & _
            '    Local $hNewOut = StringLeft($hExe, StringInStr($hExe, ".", 0, -1)) & ".patched"' & @CRLF & _
            '    FileClose(FileOpen($hNewOut, 2))' & @CRLF & _
            '    FileWrite($hNewOut, $sExe)' & @CRLF & _
            '    FileMove($hNewOut, $hExe, 1)' & @CRLF & _
            '    FileDelete("' & $hF1 & '")' & @CRLF & _
            '    FileDelete("' & $hF2 & '")' & @CRLF & _
            '    Return 1' & @CRLF & _
            'EndFunc'
    For $xCC = 1 To UBound($aOutNC) - 1
        $sWNum &= $aOutNC[$xCC][0] & Chr(1)
        $sWChr &= $aOutNC[$xCC][1] & Chr(1) & Chr(1) & Chr(1)
    Next
    $sWNum = StringTrimRight($sWNum, 1)
    $sWChr = StringTrimRight($sWChr, 3)
    FileWrite($hTempNum, $sWNum)
    FileWrite($hTempChr, $sWChr)
    FileWrite($hOutFile, $sWrite)
    Return $hOutFile
EndFunc   ;==>_CreatePatchAu3
Func _GetTempFileName()
    Local $oFSO = ObjCreate("Scripting.FileSystemObject"), $sTFolder
    $sTFolder = $oFSO.GetSpecialFolder (2)
    Return @TempDir & "\" & $oFSO.GetTempName
EndFunc   ;==>_GetTempFileName

Just didn't convert to String. And changed the way the output file (the actual patcher to be sent) checked the information.

Still doesn't make much sense as much as I condensed it, it was still 7 kbs over the actual exe size after compilation.

The only way I can see this making much since, as TKC noticed last night, is to compile as an a3x and use command line params within your app to run the patches being sent, then the patch itself turned out be 200 kbs less then the exe, which makes much more sense.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I guess I don't get what "patching" means. Try to make the first file be the second file? Why not just overwrite (FileCopy) the second file... What am I missing?

Lar.

When creating a patcher then files are compared and only the changed data are

to be written by the patcher. This can make the filesize of the patcher much smaller

compared to including all of the files to update as a whole.

For example I just made a test-patch for AutoIt (beta .9 -> .10), which was only

1.69mb, compared to the original zip which was 4.24mb.

Link to comment
Share on other sites

I guess I don't get what "patching" means. Try to make the first file be the second file? Why not just overwrite (FileCopy) the second file... What am I missing?

Lar.

I would assume that in this situation he is wanting to "update" a file without having to copy the entire script. If you are updating a script on say 3000 PC's I would say that sending only what needs to be updated would be more efficient than sending the entire script.

Granted this is based completely on assumption, but that seems to me to be the only reason to not use FileCopy().

JS

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

This intrigues me... I am working on a very interesting Diff/Update script. I will post my progress in Scripts and Scraps...

Lar.

I was hoping that might intrigue you! :lmao: I am looking forward to seeing what you come up with. As I was reading this thread I was thinking of how nice that would be to be able to do what I described above, but I dont have the time right now with all of my current projects.

JS

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

  • Moderators

I would assume that in this situation he is wanting to "update" a file without having to copy the entire script. If you are updating a script on say 3000 PC's I would say that sending only what needs to be updated would be more efficient than sending the entire script.

Granted this is based completely on assumption, but that seems to me to be the only reason to not use FileCopy().

JS

I was hoping that might intrigue you! :lmao: I am looking forward to seeing what you come up with. As I was reading this thread I was thinking of how nice that would be to be able to do what I described above, but I dont have the time right now with all of my current projects.

JS

http://www.autoitscript.com/forum/index.ph...st&p=253254

That does what you are saying, I just don't see it beig feasible as an executable, however, if you program it for .a3x and use commandlines in your exe's to be update

If $cmdline[0] Then
    If StringInStr($cmdline[1], 'Something.a3x') Then
        Run(@AutoItExe & ' /Autoit3ExecuteScript "' & $cmdline[1] & '"')
    EndIf
EndIf
Then the size is up to 5 x's smaller than the executable without all the unnecssary info being sent. I had patches today with it as small as 30kbs for a 270kb app... 200kb for 1 mb app. So it made it much more realistic.

This intrigues me... I am working on a very interesting Diff/Update script. I will post my progress in Scripts and Scraps...

Lar.

I also would be interested in what it is you are thinking of doing. Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

http://www.autoitscript.com/forum/index.ph...st&p=253254

That does what you are saying, I just don't see it beig feasible as an executable, however, if you program it for .a3x and use commandlines in your exe's to be update

If $cmdline[0] Then
    If StringInStr($cmdline[1], 'Something.a3x') Then
        Run(@AutoItExe & ' /Autoit3ExecuteScript "' & $cmdline[1] & '"')
    EndIf
EndIf
Then the size is up to 5 x's smaller than the executable without all the unnecssary info being sent. I had patches today with it as small as 30kbs for a 270kb app... 200kb for 1 mb app. So it made it much more realistic.

I also would be interested in what it is you are thinking of doing.

I appreciate that SmOke_N, but I rarely use .a3x, but I may more in the future depending on client needs, and where AutoIt is at the time.

JS

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

  • Moderators

I appreciate that SmOke_N, but I rarely use .a3x, but I may more in the future depending on client needs, and where AutoIt is at the time.

JS

Yeah, that (a3x) is the only viable AutoIt way I can see. Even Larrys returns the same exact patch size as mine, so compiled it's going to be the same size, and for that, you might as well just issue a new release executable. Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Yeah, this is what i came up with. Pretty small as long as the file it is patching isn't too large. It doesn't work because i haven't been able to get it to write null characters.

#Include <String.au3>
#include <File.au3>
#include <array.au3>
$TimeStamp = TimerInit()
_ScanExes()
Msgbox(0,'Time to create patch:','It took ' & TimerDiff($TimeStamp)/1000 & ' seconds to create the patch.')
$TimeStamp = TimerInit()
_PatchExe(@ScriptDir & "\EnCodeIt2.0.exe", @ScriptDir & "\replacement.bin", @ScriptDir & "\replacementindex.txt")
Msgbox(0,'Time to patch:','It took ' & TimerDiff($TimeStamp)/1000 & ' seconds to patch.')
Func _PatchExe($filetopatch, $replacementdata, $replacementindex)
    
;~  $b_readdata =   String(FileRead($filetopatch))
    $b_readdata = FileRead($filetopatch)
    
    
    $a_bindata = StringSplit($b_readdata, "",1)
    
;~  For $tempcount = 1 to $a_bindata[0]
;~      $a_bindata[$tempcount]=String($a_bindata[$tempcount])
;~  Next
    
;~  Msgbox(0,"Bindataarray",Ubound($a_bindata))
    
    Dim $a_replacedata
    Dim $a_replacementindex
;~  _FileReadToArrayBin($replacementdata, $a_replacedata)
    
    $s_replacementdata = FileRead($replacementdata)
    
    $a_replacedata = StringSplit($s_replacementdata,"")
    ConsoleWrite("Replacementdata String length: " &Stringlen($s_replacementdata) &@LF)
    
    _FileReadToArray($replacementindex, $a_replacementindex)
    

;~  If  $b_readdata < $a_replacementindex[$a_replacementindex[0]] + StringLen($a_replacedata[$a_replacedata[0]]) Then
;~      Redim $a_bindata[$a_replacementindex[$a_replacementindex[0]] + StringLen($a_replacedata[$a_replacedata[0]])]
;~  EndIf
    ConsoleWrite("Bindatastringlen: " & StringLen($b_readdata) & @LF)
    ConsoleWrite("BinDataArray Ubound: " & UBound($a_bindata) & @LF)
    ConsoleWrite("$a_ReplacementData Ubound " & UBound($a_replacedata) & @LF)
    ConsoleWrite("$a_ReplacementIndex Ubound" & UBound($a_replacementindex) & @LF)
    $i_ReplaceCharCounter = 1
    $a_replacementindex[0] = 1
    $h_ErrorLog = FileOpen("errorlog.txt",2)
    For $i_count = 1 To Ubound($a_replacementindex) -1
;~      $byte_replacedata = StringSplit($a_replacedata[$i_count], 1)
        $a_count3 = StringSplit($a_replacementindex[$i_count],"|")
        $i_RootOffset = $a_count3[1]
        $i_OffsetMagnitude = $a_count3[2]
        For $i_count2 = $i_RootOffset To $i_RootOffset + $i_OffsetMagnitude - 1
            #cs
            ConsoleWrite("Count3[1]: " & $a_count3[1] & @LF)
            ConsoleWrite("$i_count2: " & $i_count2 & @LF)
            ConsoleWrite("Count3[2]: " & $a_count3[2] & @LF)
            ConsoleWrite("$a_BinData Ubound: " & Ubound($a_bindata) & @LF)
            #ce
;~          $a_bindata[$i_count3] = $byte_replacedata[$i_count2]
            $i_ReplaceCharCounter+= 1
            #cs
            FileWrite($h_ErrorLog,'The UBOUND of $a_bindata is: ' & Ubound($a_bindata) & _
            ' The value of $a_count3[1] is: ' & $a_count3[1] & ' The value of $i_RootOffset + $i_OffsetMagnitude is: ' & $i_RootOffset + $i_OffsetMagnitude & ' The value of $a_count3[2] is: '& $a_count3[2] & _
            ' The ubound of $a_replacedata is: ' & Ubound($a_replacedata) & ' The value of $i_ReplaceCharCounter is: ' & $i_ReplaceCharCounter & @LF)
            #ce
            $a_bindata[$a_count3[1]] = $a_replacedata[$i_ReplaceCharCounter]
            $a_count3[1] += 1
        Next
        $a_count3 = ""
    Next
    FileClose($h_ErrorLog)
;~  _FileCreate(@ScriptDir & "\EnCodeIt2.0 patched.exe")
    
    ReDim $a_bindata[INIRead('patchdata.dat','New File','Size',1)+1]
    
;~  _FileCreate(@ScriptDir & "\EnCodeIt2.0 patched.exe")
;~  FileWrite(@ScriptDir & "\EnCodeIt2.0 patched.exe",BinaryString(_ArrayToString($a_bindata,"",1)))
    $h_patchedfile = FileOpen(@ScriptDir & "\EnCodeIt2.0 patched.exe", 2)
;~  FileWrite(@ScriptDir & "\EnCodeIt2.0 patched.exe",_ArrayToString($a_bindata,"",1))
;~  ConsoleWRite("Ubound of $bincount: " & Ubound($a_bindata) - 1)
    For $bincount = 1 To UBound($a_bindata) - 1
        FileWrite($h_patchedfile, $a_bindata[$bincount])
;~      ConsoleWrite("Writing Bin data " & $a_bindata[$bincount])
    Next
    
    FileClose($h_patchedfile)
    
    #cs
        ;~  $a_replacedata = StringSplit(BinaryString(FileRead($replacementdata)),@CRLF)
        ;~  $a_replacedata = _ArrayDelete($a_replacedata1,0)
        
        Msgbox(0,"$a_replacedata Ubound", Ubound($a_replacedata) & " "& $a_replacedata[0])
        $a_ubound = StringSplit($a_replacedata[$a_replacedata[0]],@CR)
        IF @error Then
        ConsoleWRite($a_replacedata[$a_replacedata[0]])
        ;~      Msgbox(0,"Error after splitting to $a_ubound", @error )
        ;~      Exit
        ;~      dim $a_ubound[3]
        ;~      $a_ubound[1] = Ubound($a_replacedata
        ;~      $a_ubound = StringSplit($a_replacedata[$a_replacedata[0]] & " ",@CR)
        Endif
        If UBound($a_ubound) >= 3 Then
        Redim $a_bindata[$a_ubound[1] + StringLen($a_ubound[2])]
        Else
        ;~      ConsoleWRite(@CRLF & $a_replacedata[$a_replacedata[0]])
        _ArrayDisplay($a_ubound,"Uboundarray")
        ;~      Msgbox(0,"ERROR","There was an error.")
        Redim $a_bindata[$a_ubound[1]]
        Endif
        
        For $i_counter = 1 to $a_replacedata[0]
        $a_splitreplacedata = StringSplit($a_replacedata[$i_counter],@CR,1)
        ConsoleWrite($a_replacedata[$i_counter] & @LF & "Number is " & $a_splitreplacedata[1])
        $a_splitreplacedata[2] = StringTrimLeft($a_replacedata[$i_counter],StringLen($a_splitreplacedata[1]))
        ConsoleWrite(@LF & "Data is " & $a_splitreplacedata[1])
        #cs
            $i_CRpos = StringInStr($a_replacedata[$i_counter],@CR,1,1)
            Dim $a_splitreplacedata[3]
            $a_splitreplacedata[1] = StringLeft($a_replacedata[$i_counter],$i_CRpos - 1)
            ConsoleWrite($a_replacedata[$i_counter] & @LF & "Number is " & $a_splitreplacedata[1])
            $a_splitreplacedata[2] = StringTrimLeft($a_replacedata[$i_counter],$i_CRpos)
            ConsoleWrite(@LF & "Data is " & $a_splitreplacedata[1])
        #ce
        
        $a_splitreplacebytes = StringSplit($a_splitreplacedata[2], "")
        
        $i_counter3 = 0
        If UBound($a_splitreplacedata) >= 3 Then
;~          For $i_counter2 = $a_splitreplacedata[1] to  $a_splitreplacedata[1] + StringLen($a_splitreplacedata[2])
            For $i_counter2 = $a_splitreplacedata[1] To StringLen($a_splitreplacedata[2] - 1)
;~              $a_splitreplacebytes[$i_counter3]
                $i_counter3 += 1
                
;~              Msgbox(0,"Error","The array $a_splitreplacebytes has " & UBound($a_splitreplacebytes) & " elements and it was called with the number " & $i_counter3)
;~              Msgbox(0,"Data:",$a_splitreplacedata[2]
;~              If Ubound($a_splitreplacebytes) > 1 Then
                
                $a_bindata[$i_counter2] = $a_splitreplacebytes[$i_counter3]
;~              Endif
            Next
        Else
            _ArrayDisplay($a_splitreplacedata, "Array data")
            $a_bindata[$a_splitreplacedata[1]] = ""
        EndIf
;### Tidy Error -> "next" is closing previous "#cs"
    Next
#ce
;### Tidy Error: next line creates a negative tablevel.
;### Tidy Error: next line creates a negative tablevel for the line after it.
EndFunc   ;==>_PatchExe
Func _ScanExes()
    $s_ftpname = @ScriptDir & "\v2\EnCodeIt2.0.exe"
    $s_fapname = @ScriptDir & "\v3\EnCodeIt2.0.exe"
    $h_filetopatch = FileOpen($s_ftpname, 0)
    $h_filealreadypatched = FileOpen($s_fapname, 0)
#cs
    $b_ftp = String(FileRead($h_filetopatch));,FileGetSize($s_ftpname))
    $b_fap = String(FileRead($h_filealreadypatched));,FileGetSize($s_fapname))
    $sb_FTP = $b_ftp
    $sb_FAP = $b_fap
#ce
    $sb_FTP= FileRead($h_filetopatch)
    $sb_FAP = FileRead($h_filealreadypatched)
    
    $i_FTPlen = StringLen($sb_FTP)
    $i_FAPlen = StringLen($sb_FAP)
;~ FileWrite("test1.txt",$sb_FTP)
;~ FileWrite("test2.txt",$sb_FAP )
    $ab_FTP = StringSplit($sb_FTP, "")
    $ab_FAP = StringSplit($sb_FAP, "")
    If $i_FTPlen > $i_FAPlen Then
        ;file that is being patched is larger than the final file
;~      $i_maxlen = $i_FTPlen
;~      ReDim $ab_FAP[$i_FTPlen + 1]
        $i_maxlen = $i_FAPlen
        ReDim $ab_FTP[$i_FAPlen + 1]
        $mode = -1 ;because it has to make the file smaller
    ElseIf $i_FTPlen < $i_FAPlen Then
        ;file that is being patched is smaller than the final file
        $i_maxlen = $i_FAPlen
        $mode = 1 ;beause it has to make the file bigger
        ReDim $ab_FTP[ $i_FAPlen + 1]
    Else
        ;The lengths are the same
        $i_maxlen = $i_FAPlen
        $mode = 0 ;because it doesn't have to increase or decrease its size
    EndIf
    INIWrite('patchdata.dat','Original File','Size',FileGetSize($s_ftpname))
    IniWrite('patchdata.dat','New File','Size',FileGetSize($s_fapname))
    ConsoleWrite($i_maxlen &@LF)
    ConsoleWrite($sb_FTP &@LF )
    ConsoleWrite($sb_FAP &@LF)
    $firstline = True
    Dim $s_replacement
    $h_filereplace = FileOpen("replacement.bin", 2)
    $h_filereplaceindex = FileOpen("replacementindex.txt", 2)
    $i_countprevious = 0
    $o_FileReplace = ''
    $i_BytesToReplace = 0
    For $i_counter = 1 To $i_maxlen
        If $ab_FTP[$i_counter] <> $ab_FAP[$i_counter] Then
            If $i_counter - $i_countprevious = 1 Then
                FileWrite($h_filereplace, $ab_FAP[$i_counter])
;~              $o_FileReplace &= @CRLF & $ab_FAP[$i_counter]
                $i_BytesToReplace += 1
            Else
                If $firstline = False Then
                    FileWrite($h_filereplace, $ab_FAP[$i_counter])
;~                  $o_FileReplace &=  @CRLF & $ab_FAP[$i_counter]
                    FileWrite($h_filereplaceindex, "|" & $i_BytesToReplace & @CRLF & $i_counter)
                    $i_BytesToReplace = 0
                Else
                    FileWrite($h_filereplace, $ab_FAP[$i_counter])
;~                  $o_FileReplace &= $ab_FAP[$i_counter]
                    FileWrite($h_filereplaceindex,  $i_counter)
                    $i_BytesToReplace = 0
                EndIf
            EndIf
            $firstline = False
            $i_countprevious = $i_counter
        EndIf

#cs
        If IsInt($i_counter / 1000) Then
            ConsoleWrite($i_counter & @LF)
        EndIf
#ce

    Next
    FileWrite($h_filereplaceindex,"|" & $i_BytesToReplace)
;~  FileWrite("replacement.bin",$o_FileReplace)
    FileClose($h_filereplaceindex)
    FileClose($h_filereplace)
    FileClose($h_filetopatch)
    FileClose($h_filealreadypatched)
EndFunc   ;==>_ScanExes
Func _FileReadToArrayBin($sFilePath, ByRef $aArray)
    Local $hFile
    $hFile = FileOpen($sFilePath, 0)
    If $hFile = -1 Then
        SetError(1)
        Return 0
    EndIf
    $aArray = StringSplit(FileRead($hFile, FileGetSize($sFilePath)), @CRLF, 1)
    FileClose($hFile)
    Return 1
EndFunc   ;==>_FileReadToArrayBin

Here are some patchers that i found that seem to be fairly good. My favorite at the moment would have to be cold fusion for its simplicity and the fact that it works really well.

http://www.softpedia.com/catList/15,1,1,1.html

I know AutoIt wasn't meant for this purpose and cannot compare to these as far as speed and efficientcy are concerned, however, i do think it would be neat to be able to create a patcher in autoit.

EDIT

For those of you that don't understand what i mean by a patcher i have made the following diagram:

Posted Image

The diagram above represents a string of new binary data at the bottom and old binary data at the top. The patcher acts as the mediator and only stores the changed data and the position of where to place the changed data in the old exe to make it exactly like the new one. As a result, the patch only has to contain the changed data from the new to the old and not an entirely new exe. As a result, a mild change of version doesn't require a massive re-download of the whole program, but only a small patch with the varied data. What my patcher does is find the difference between the two exes, it then writes the data to three files that it can use as a database to store the varied information. You then simply use a fileinclude() when creating the exe or a3x patch file and then send it on its way. By doing this you can significantly reduce the size of the update. So far i only have two problems, one is with an array when patching which shows up here and there, i am betting it has something to do with the fact that the StringSplit() is deleting all the null characters out of the string and therefore the array isn't being made large enough since the null characters are missing and therefore causing an invalid element error(you have exceeded the number of elements of this array, blah blah).

-The Kandie Man

Edited by The Kandie Man

"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...