In Datei Werte suchen und ändern ( Hex Datei )

  • Ach ja, man kann ja die Datei auch im Textmodus auslesen, stimmt ja. Man muss nur hoffen, dass nicht aus versehen in einen UTF-Lesemodus geschaltet wird.

  • Vielleicht mein progandy sowas:

    Spoiler anzeigen
    [autoit]


    #include <FileConstants.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $run = FileBinReplace("ap.txt", "3030", "7878") ;suche nach Hex 3030 und ersetze es mit Hex 7878 -> 00->xx
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $run = ' & $run & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    Func FileBinReplace($filename, $search, $replace) ;coded by UEZ build 2011-03-15 ßeta
    If $filename = "" Then Return SetError(1, 0, 0)
    If Not FileExists($filename) Then Return SetError(2, 0, 0)
    If $search = "" Or $replace = "" Then Return SetError(3, 0, 0)
    Local $data
    If Mod(StringLen($search), 2) = 1 Then $search = "0" & $search
    If Mod(StringLen($replace), 2) = 1 Then $replace = "0" & $replace
    If StringLen($search) <> StringLen($replace) Then Return SetError(4, 0, 0)
    Local $aTokens = StringRegExp($search, ".{2}", 3)
    If Not IsArray($aTokens) Then Return SetError(5, 0, 0)
    Local $len = UBound($aTokens)
    Local $flen = FileGetSize($filename)
    If @error Or $flen = 0 Then Return SetError(6, 0, 0)
    Local $hFile = FileOpen($filename, 16 + 1)
    If @error Then Return SetError(7, 0, 0)
    Local $pos = 0, $i = 0, $old_pos = 0, $c = 0
    While $pos < $flen + 1
    $old_pos = $pos
    While $i < $len
    FileSetPos($hFile, $pos, $FILE_BEGIN)
    If "0x" & $aTokens[$i] <> FileRead($hFile, 1) Then ExitLoop
    $pos += 1
    $i += 1
    WEnd
    If $i = $len Then
    FileSetPos($hFile, $old_pos, $FILE_BEGIN)
    FileWrite($hFile, "0x" & $replace)
    $pos += $len - $i
    $c += 1
    Else
    $pos += 1
    EndIf
    $i = 0
    WEnd
    FileFlush($hFile)
    FileClose($hFile)
    Return SetError(0, 0, $c)
    EndFunc

    [/autoit]

    Keine Ahnung, ob das schneller oder besser ist - ist einfach nur ein Konzept Code.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    3 Mal editiert, zuletzt von UEZ (16. März 2011 um 14:22)

  • Man muss nur hoffen, dass nicht aus versehen in einen UTF-Lesemodus geschaltet wird.


    Stimmt, daran denke ich immer wieder mal nicht. ;)

    Das Risiko ist aber bei "bekannten" Dateien, von denen man weiß, dass sie Binärdaten enthalten, nicht wirklich groß. In der Regel enthalten sie in den ersten paar Bytes ein Typkennzeichen und sollten deshalb nicht mit einer BOM beginnen.

    Bleibt noch die automatische UTF8-Erkennung. Ich weiß nicht, unter welchen Umständen und in welchem Bereich AutoIt nach typischen UTF8-Bytefolgen sucht. Spätestens beim ersten NULL-Byte sollte aber Schluss sein.

    Und wenn man nicht sicher ist, ob AutoIt auch der Meinung ist, dass es sich um Binärdaten handelt, kann man das per FileGetEncoding() abfragen und notfalls in den "binary mode" wechseln.

  • Erst einmal Danke für die Vorschläge von euch.
    @progandy
    Da bin ich wohl nicht so weit mit Autoit das ich deine Funktion auch nutzen kann.
    Hatte da so einiges probiert aber leider ohne Erfolg, keine Ahnung wie ich da den Aufruf machen soll.

    Habe dann einfach, bestärkt durch Großvater, die Daten als normale behandelt.
    Bei den Versuch mal einen Chunk zu trennen, wo ich meinte das es wohl einfacher ist als etwas zu tauschen kommen
    immer 128 bit mehr bei raus. Diese werden als 0Bite (FF) an die erstellte Datei angehängt.
    Habe es mal so probiert:

    [autoit]

    $message = "Gehen nur(*.abs Dateien )"
    $var = FileOpenDialog($message, @ScriptDir & "\", "Images (*.abs;*.txt)", 1 + 4 )
    If @error Then
    MsgBox(4096,"","Ups!" & @CRLF & "nichts Ausgewählt")
    Else
    $File = FileOpen($var,16)
    $Replace = BinaryToString($File)
    $BinFile = FileRead($File)
    $teilen = StringSplit($BinFile, "EF1010AC",1)
    $erster = FileOpen("erster.abs",16+2)
    FileWrite($erster, $teilen[1])
    FileClose($erster)
    FileClose($File)
    EndIf

    [/autoit]


    Und hier mal eine Datei:
    Klicke mich
    Ups genau 0,06 zu groß deswegen ul.to

    Wie kann es sein das es immer genau 128bit sind ?
    Habe aber auch noch nicht geschafft einen anderen Chunk zu trennen. Da bin ich noch am Testen.


    mfg
    oh-ha

    Es gibt drei Wahrheiten: deine Wahrheit, meine Wahrheit und die Wahrheit