Batch Per DOS Batch in Datei nach Hex Sequenz suchen und Stelle dahinter ersetzen

Phoenix22

Cadet 1st Year
Registriert
Jan. 2023
Beiträge
14
Hallo zusammen😊
Es wäre toll wenn mir jemand bei einem kleinen DOS Batch helfen könnte.
Folgendes mache ich immer per Hex Editor (ich nutze HxD) und würde das gerne per DOS Batch machen können:

Ich suche nach einem (in der Regel einmalig vorkommenden) Hex Wert mit 16 Zeichen bzw. 8 Bytes, z. B.
Code:
52 80 20 04 04 80 04 52
Die 8 Zeichen, also 4 Bytes, direkt dahinter ersetze ich dann durch einen neuen Wert, z. B.
Code:
20 20 20 20

also nochmal als Beispiel:
vorher...: 52 80 20 04 04 80 04 52 04 04 80 80
nachher: 52 80 20 04 04 80 04 52 20 20 20 20

Kann man das per DOS Batch realisieren ?
Lieben Dank im voraus. 🤗
 
Zuletzt bearbeitet:
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: nutrix
Hallo, danke schonmal für die schnelle Reaktion.
Der BinaryFilePatcher sieht nett aus, aber der ersetzt ja leider nur die gesuchte Stelle selbst.
Frage dort aber gerade, ob man da evtl. bei der Suche Wildcards nutzen kann.
bsdiff ist leider schon too much für mich.
Daher wäre ein kontreker Code Vorschlag von jemanden schon gut.
 
A) wenn du(!) noch ein DOS hast nat. nicht - cmd ist kein Dos :Augenroll:
B) du kannst jede Datei dieser Welt zu einem Windows/Unix bringen wo dir passenden Tools sind

ja kein Dos Tool aber auch SED könnte dir helfen
 
Zuletzt bearbeitet:
Ok, danke.
Mein Frage war allerdings nicht, ob es Tools gibt, sondern wie man das in einem DOS Batch programmieren kann.

So kann man ja z. B. Text an sich ersetzten:
Code:
@echo off
setlocal enabledelayedexpansion

set "filename=text.txt"
set "tempfile=tmptxt.txt"

for /F "delims=" %%a in (%filename%) do (
set text=%%a
set text=!text:^vorher=nachher!>>%tempfile%
)

del %filename%

So ähnlich, wenn natürlich auch komplexer, muss es doch auch mit Hex Werten gehen.
 
dms schrieb:
ja kein Dos Tool aber auch SED könnte dir helfen
Wäre mir neu, wenn sed mit Binärdateien und Hexcodes umgehen könnte.
Ergänzung ()

Phoenix22 schrieb:
Die 8 Zeichen, also 4 Bytes, direkt dahinter ersetze ich dann durch einen neuen Wert, z. B.
Code:
20 20 20 20
Willst Du wirklich mit Leerzeichen ersetzten oder ist das nur ein Beispiel?

Was willst Du denn überhaupt genau machen, vielleicht ist das wieder ein X-Y Problem?
 
nutrix schrieb:
Willst Du wirklich mit Leerzeichen ersetzten oder ist das nur ein Beispiel?

Was willst Du denn überhaupt genau machen, vielleicht ist das wieder ein X-Y Problem?
Hallo 😊
Nein, das ist nur ein Beispiel.
Es geht um das Patchen einer Datei, die sich nach Updates ändert.
Ich mache das ansonsten wie oben beschrieben manuell per HxD.
Ergänzung ()

Ich habe aber wohl schon gelesen, dass es per DOS Batch direkt nicht geht, also muss ich wohl Tools benutzen.
 
Zuletzt bearbeitet:
Phoenix22 schrieb:
Mein Frage war allerdings nicht, ob es Tools gibt, sondern wie man das in einem DOS Batch programmieren kann.

So kann man ja z. B. Text an sich ersetzten:
Code:
@echo off
setlocal enabledelayedexpansion
...
Das ist aber für ein DOS Batch nicht korrekt. Setlocal ist ein Windows-Kommando, das wird auf keinem DOS laufen. Denn:
dms schrieb:
Lösungsorientiert zu fragen wäre u.U. zielführender.
 
Oh, sorry, bin ein Noob.
Schreibe mir kleine Tools in *.bat Dateien. Dann ist es wohl cmd.
Zum einen für Command Line Ausführungen diverser Windows-Tools, zum anderen für Datei Handling.
Fehlt jetzt nur noch diese Hex Editierung.
 
Hab's selber herausgefunden. 🥳
Das tolle Tool, das mir geholfen hat, ist JREPL, selbst eine Bat-Datei.
Arbeitet sogar mit Wildcards, was ja Voraussetzung war. Klasse.
Trotzdem danke an alle und sorry für meine vielleicht schlecht gestellte Frage.
 
Sorry, sagte ja, bin ein Noob.
Dachte mit bat-Dateien mache ich DOS Batches. 🫣
 
Schön, dass du eine Lösung für dich gefunden hast.
Der Satz
Mein Frage war allerdings nicht, ob es Tools gibt, sondern wie man das in einem DOS Batch programmieren kann.
kam vielleicht etwas schlecht an bei manchen im Forum, weil dir ja gewisse Möglichkeiten und Ansätze genannt wurden. Jetzt im Nachhinein bist du ja mit deiner gefundenen Lösung mit extra Tool auch zufrieden.
Im Übrigen kann man sich die benötigte Funktionalität alternativ auch in einem kleinen Programm selbst zusammenschreiben. Nur halt nicht in Batch, weil - ich zitiere Boardie @Raijin - Batch is a bitch!
Das ist eine ziemliche Krücke und quasi überall, wo man .bat Dateien verwenden kann, ist auch Powershell verfügbar, was insgesamt deutlich angenehmer sein dürfte.
Und natürlich kann man auch aus einem .bat heraus einfach andere Programme aufrufen.

C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int move_buffer(char buffer[], char len) {
    int i=0;
    for (i = 0; i < len-1; i++) {
        buffer[i] = buffer[i+1];
    }
}

int found_match(char buffer[], char len, char search_stream[]) {
    int i=0, match_count=0;
    for (i = 0; i < len; i++) {
        if (buffer[i] == search_stream[i]) {
            match_count++;
        }
    }
    if (!(match_count==len)) {
        return 0;
    }
    return 1;
}

int put_replace_stream(FILE *filehandle, char len, char put_stream[]) {
    fseek(filehandle, 0, SEEK_CUR);
    int ret = fwrite(put_stream, sizeof(char), len, filehandle);
    fseek(filehandle, 0, SEEK_CUR);
    if (ret==len) {
        //printf("\nwrote %d chars\n", ret);
        return 1;
    } else {
        //printf("\nwrote %d chars\n", ret);
        return 0;
    }
}

int modify_file(char *org_filename, char len_seach_stream, char search_stream[],
    char len_put_stream, char put_stream[]) {
        
        char *buffer;
        buffer = malloc(len_seach_stream*sizeof(char));
        char new_char, dummy;
        int n_replaced = 0;
        
        FILE *fptr;
        fptr = fopen(org_filename, "r+b");
        if(fptr == NULL) {
            return 2;
            
        }
        while(!feof(fptr)) {
            move_buffer(buffer, len_seach_stream);
            fread(&new_char, sizeof(char), 1, fptr);
            buffer[len_seach_stream-1] = new_char;
            
            if (found_match(buffer, len_seach_stream, search_stream)) {
                //printf("Found Match");
                if (put_replace_stream(fptr, len_put_stream, put_stream)) {
                    n_replaced++;
                }
            }
        }
        fclose(fptr);
        printf("Found and put %d occurrences.", n_replaced);
        return 0;
}

int main(int argc, char *argv[])
{
    if(argc < 4) {
        printf("Searches for a series of bytes within a file and replaces the bytes after those with a specified series. Search and replace up to 10 bytes.\nUsage: [executable] filename \"search bytes\" \"replace-after bytes\"\n");
        return 1;
    }
    char *org_filename = argv[1];
    
    char search_stream[10];
    char put_stream[10];
    
    int len_seach_stream=0, len_put_stream=0;
    len_seach_stream = sscanf(argv[2], "%x %x %x %x %x %x %x %x %x %x", search_stream, search_stream+1, search_stream+2, search_stream+3, search_stream+4, search_stream+5, search_stream+6, search_stream+7, search_stream+8, search_stream+9);
    len_put_stream = sscanf(argv[3], "%x %x %x %x %x %x %x %x %x %x", put_stream, put_stream+1, put_stream+2, put_stream+3, put_stream+4, put_stream+5, put_stream+6, put_stream+7, put_stream+8, put_stream+9);
    
    printf("Search Length: %d\n", len_seach_stream);
    printf("Replace Length: %d\n", len_put_stream);
    modify_file(org_filename, len_seach_stream, search_stream, len_put_stream, put_stream);

    return 0;
}
 
  • Gefällt mir
Reaktionen: Ranayna, nutrix, Phoenix22 und 2 andere
Zurück
Oben