In Datei Werte suchen und ändern ( Hex Datei )

  • Moin moin,

    Kann man mit Autoit Werte in einer Datei suchen und auch ändern, aber das ganze dann in einer Hex Datei ?
    In dieser Form habe ich es mit WinHex:
    [Blockierte Grafik: http://geiler-bildhost.de/upload/1299846360.jpg]
    Das blau makierte möchte ich suchen und 64 Byte (FF) darunter Löschen.
    Das ganze soll dann auch wieder gespeichert werden.

    Habe noch nicht mal im Ansatz eine Ahnung wie man derartiges machen könnte, wenn es denn geht.


    mfg
    oh ha

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

  • Ist eine *.abs Datei
    Zumindest meckert Autoit nicht wenn ich sie einlese.

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

  • Hi autoBert,

    naja von Hand geht das ja alles.
    Wollte halt nur mal Wissen ob und wenn wie man das mit Autoit machen könnte.


    mfg
    oh-ha

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

  • Mit FileOpen("Datei.txt", 16) kannst du eine Datei im Binärmodus einlesen. Das ganze befindet sich nach dem auslesen auch schon in Hexadezimalform. Danach müsstest du im Grunde nur noch mit StringInStr StringReplace etc. arbeiten ;). Dann schreibst du das ganze wieder in die Datei. Also so:

    [autoit]

    $hFile = FileOpen("Test.txt", 16)
    $vData = FileRead($hFile)
    ;Hier kannst du mit dem String machen was du willst...
    FileClose($hFile)

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

    $hFile = FileOpen("Test.txt", 18)
    FileWrite($vData)
    FileCLose($hFile)

    [/autoit]
  • Hallo name22,

    danke für deinen anstoß, war wohl das was ich gebraucht habe. :thumbup:
    Geht zwar derzeitig noch nicht mit StringInStr, StringReplace usw aber ich probiere noch.


    mfg
    oh-ha

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

  • Zitat von autoBert

    natürlich ist das machbar, ich bezweifle aber dass du danach noch eine gültige Datei hast


    Das du aber auch ( fast ) immer recht behalten mußt. :rolleyes:

    Habe einiges probiert, _StringBetween, StringInStr, StringSplit aber kam meist nur müll dabei raus.
    Entweder bin ich zu blöd dafür oder es geht halt nicht mit autoit.
    Muss ich mich wohl auch weiterhin mit CodeFusion begnügen und per hand die dateien ändern. ;(


    mfg
    oh-ha

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

  • Hallo oh-ha,

    stelle doch mal eine Testdatei und auch Infos über das Dateiformat bereit, vielleicht schaffst ja doch jemand,

    zu abs finde ich 3 Möglichkeiten:
    .abs abstract Zusammenfassung eines (wissenschaftlichen) Dokuments
    .abs – Standard GNU-Compiler-Ausgabe für die PC-Plattform
    .abs Absolute Database BDE-Datenbanksystem der Fa. ComponentAce

    bei 2+3 hast du meines Erachtens wirklich keine Chance einfach so etwas herauszuschneiden,

    mfg autoBert

  • Du kannst die Datei ja Byte für Byte durchgehen, bis du das Suchmuster findest. Machbar ist es auf jeden Fall, aber aufwendig.

    • Offizieller Beitrag

    Beim benutzen von StringInStr mit einer Binärdatei (Mode 16) musst Du beachten, dass jeweils zwei Zeichen (Hex) ein Byte repräsentieren.
    Demzufolge musst Du das Ergebnis von StringInStr durch zwei teilen und außerdem noch 1 abziehen, weil die Datei bei Null beginnt und StringInStr aber 1 als erstes Zeichen ausgibt.
    Das Ganze sieht dann in etwa so aus:

    [autoit]


    $hFile = FileOpen(@ScriptDir & '\file.bin', 16)
    If $hFile <> -1 Then
    $sFile = FileRead($hFile)
    FileClose($hFile)
    $sFound = Hex(StringInStr($sFile, '08F70100') / 2 - 1)
    EndIf

    [/autoit]
  • Ok, stimmt! Man müsste noch prüfen, ob das Ergebnis von StringInStr - 1 = gerade ist. Bei ungerade ist es ein "falscher Treffer".


    Es müsste auch so gehen:

    Spoiler anzeigen
    [autoit]

    Func _BinaryFind($bBinary, $bFind, $iOccurence = Default, $iStart = Default, $iCount = Default)
    ; ProgAndy
    $bBinary = BinaryToString($bBinary, 0)
    $bFind = BinaryToString($bFind, 0)
    Switch @NumParams
    Case 2
    Return StringInStr($bBinary, $bFind, 1)
    Case 3
    Return StringInStr($bBinary, $bFind, 1, $iOccurence)
    Case 4
    If IsKeyword($iOccurence) Or $iOccurence = 0 Then $iOccurence = 1
    Return StringInStr($bBinary, $bFind, 1, $iOccurence, $iStart)
    Case Else
    If IsKeyword($iOccurence) Or $iOccurence = 0 Then $iOccurence = 1
    If IsKeyword($iStart) Or $iStart = 0 Then $iStart = 1
    Return StringInStr($bBinary, $bFind, 1, $iOccurence, $iStart, $iCount)
    EndSwitch
    EndFunc

    [/autoit]
  • Ersteinmal Danke das ihr da weitergemacht habt wo ich schon aufgegeben hatte.

    Melde mich erst jetzt da ich versucht habe das über eine batch zu machen mit hexciting.
    Hätte man ja auch über autoit dann steuern können.
    Wäre mir natürlich lieber das alles über autoit zu machen, wenn es denn geht.
    @ progandy,
    werde das mal testen und berichten. Wird aber etwas dauern da ich über die woche weg bin und nicht weiss ob es da internet gibt.

    Edit: autoBert

    Zitat

    stelle doch mal eine Testdatei und auch Infos über das Dateiformat bereit, vielleicht schaffst ja doch jemand,


    Ist eine Firmware für einen Receiver.
    Per hand kann ich da so einiges ändern. Nur das sollte besser nicht öffentlich behandelt werden.
    Könnten sich so einige den receiver schrotten.
    Habe ein kleines forum und stelle da dann die geänderten firms zur verfügung.
    Wollte mir nur die arbeit etwas erleichtern und nicht immer von hand im code rumstochern.
    Hmm der schuß ging wohl etwas nach hinten los. :rolleyes:


    mfg
    oh-ha

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

    2 Mal editiert, zuletzt von oh-ha (13. März 2011 um 19:10)

  • Hallo,

    binäres Suchen und/oder Ersetzen in eingelesenen Dateien ist erstaunlich einfach. Die dafür notwendigen String-Anweisungen von AutoIt können mit Ausnahme der RegExp-Engine perfekt mit NULL-Bytes umgehen.

    Spoiler anzeigen
    [autoit]

    ; Ggf. Installationsverzeichnis anpassen
    $File = @ProgramFilesDir & "\AutoIt3\Examples\GUI\Torus.png"
    $Diff = 12 ; 12 Bytes hinter Fundposition ersetzen
    $Replace = BinaryToString("0xFF00FF00FF00FF00FF00FF00FF00FF00")
    $BinFile = FileRead($File, 48)
    $Find = BinaryToString("0x000D4948445200")
    $Pos = StringInStr($BinFile, $Find)
    If $Pos Then
    $Out = StringReplace($BinFile, $Pos + $Diff, $Replace)
    EndIf
    MsgBox(0, "Binary", StringToBinary($BinFile) & @CRLF & StringToBinary($OUT))

    [/autoit]
  • @Großvater: Es funktoniert, ist aber nicht wirklich effizient. Besser wäre es, wenn man direkt auf den Daten suchen könnte und sie nicht erst kopieren müsste. Übrigens hab ich das in meinem letzen Post bereits verwendet ;)

    Einmal editiert, zuletzt von progandy (14. März 2011 um 14:34)

  • @progandy: Wo werden in meinem Beispiel Daten für die Suche kopiert? Die Variable $Out dient doch nur der Gegenüberstellung in der MsgBox, da kann auch getrost $BinFile stehen. ;)

  • Großvater: Du hast Daten im Binärformat und diese musst du erst per BinaryToString kopieren. Es wäre einfach viel praktischer, wenn man direkt auf den Daten suchen könnte ohne sie in einen String zu kopieren.

  • progandy: Ich habe Daten aus einem einfachen FileRead(). Ich habe in meinem Beispiel lediglich den den Suchbegriff per BinaryToString() aufgebaut. Wo ist denn das Problem?

    [autoit]

    ; Ggf. Installationsverzeichnis anpassen
    $File = @ProgramFilesDir & "\AutoIt3\Examples\GUI\Torus.png"
    $Diff = 12 ; 12 Bytes hinter Fundposition ersetzen
    $Replace = BinaryToString("0xFF00FF00FF00FF00FF00FF00FF00FF00")
    $BinFile = FileRead($File, 48)
    $Find = BinaryToString("0x000D4948445200")
    $Pos = StringInStr($BinFile, $Find)
    If $Pos Then
    FileDelete("Dummy.png")
    FileWrite("Dummy.png", StringReplace($BinFile, $Pos + $Diff, $Replace))
    EndIf
    $NewFile = FileRead("Dummy.png")
    MsgBox(0, "Binary", StringToBinary($BinFile) & @CRLF & StringToBinary($NewFile))

    [/autoit]

    Oder meinst du das?

    [autoit]

    $Find = Chr(0x00) & Chr(0x0D) & Chr(0x49) & Chr(0x48) & Chr(0x44) & Chr(0x52) & Chr(0x00)

    [/autoit]

    Das funktioniert natürlich auch!