(erledigt) start und end offset von Zeichenkette xyz aus Binärdatei ausgeben
(erledigt) start und end offset von Zeichenkette xyz aus Binärdatei ausgeben
Hallo,
gibt es ein einfache Möglichkeit, im Terminal, sich aus einer Binärdatei ( HDD-Image / ISO-Image ), den Start und End Offset von einer gesuchten Zeichenkette ausgeben zulassen, der auch über mehrere Zeilen geht, also inklusive newlines ?
Vielen Dank
gibt es ein einfache Möglichkeit, im Terminal, sich aus einer Binärdatei ( HDD-Image / ISO-Image ), den Start und End Offset von einer gesuchten Zeichenkette ausgeben zulassen, der auch über mehrere Zeilen geht, also inklusive newlines ?
Vielen Dank
Zuletzt geändert von ren22 am 15.12.2019 17:14:31, insgesamt 1-mal geändert.
Re: start und end offset von Zeichenkette xyz aus Binärdatei ausgeben
Wenn es eine Binaerdatei ist, dann sind Newlines irrelevant. Du solltest ein Programm fuer Binaerdaten verwenden, wenn du diese Aktion ausfuehrst, da Textprogramme von Newlines und Null-Bytes beeinflusst werden.ren22 hat geschrieben:07.12.2019 14:00:32gibt es ein einfache Möglichkeit, im Terminal, sich aus einer Binärdatei ( HDD-Image / ISO-Image ), den Start und End Offset von einer gesuchten Zeichenkette ausgeben zulassen, der auch über mehrere Zeilen geht, also inklusive newlines ?
Was du also suchst ist eine Art Substring() fuer Dateien.
Keine Ahnung, ob's ein Standardprogramm gibt, das das kann. Falls niemand eines kennt, kann man das auch schnell in C programmieren. Programmier-Contest anyone?
Btw: Den End-Offset brauchst du nicht, da der Start + length(Suchstring) ist.
Nachtrag: Evtl. koennte dir sowas wie:
Code: Alles auswählen
strings -t d image | grep suchstring
Use ed once in a while!
Re: start und end offset von Zeichenkette xyz aus Binärdatei ausgeben
mit grep habe ich das Problem, wenn Zeichen 'LF' ->HEX:0A enthalten sind, muss ich die "-z" Option verwenden.Wenn es eine Binaerdatei ist, dann sind Newlines irrelevant.
...naja momentan mache ich das so, aber das "grep" gibt mir leider nicht von A bis B aus, sondern alle Zeichenketten.
Code: Alles auswählen
grep -barz 'GESUCHTER_STRING_START_MARKER.*GESUCHTER_STRING_END_MARKER' Binärdatei.img
527794176:<?xml version="1.0"?>
TEXT TEXT TEXT
TEXT TEXT TEXT
TEXT TEXT TEXT
<END_MARKER>
527826944:<?xml version="1.0"?>
TEXT TEXT TEXT
TEXT TEXT TEXT
TEXT TEXT TEXT
<END_MARKER>
...usw.
Mein Problem ist immo, dass in der Binärdatei der "END Marker" mehrfach enthalten ist und "grep" alle Zeichen bis zum letzten "END Marker" ausgibt. Wenn ich nur nach dem "END Marker" als String suche weiss ich nicht welcher dann der richtige "END Offset" ist, weil ja mehrfach... aber ich bin noch am suchen & probieren.
*mit "strings" hatte ich das schon probiert aber das ist leider langsam im Gegensatz zu "grep"
Die Zeichenkettenlänge ist vorerst unbekannt, ich erhalte sie von der Zeichenkette die ich per "grep" mittels Start & End Marker bekomme, so meine Idee.Btw: Den End-Offset brauchst du nicht, da der Start + length(Suchstring) ist.
Danke
Zuletzt geändert von ren22 am 07.12.2019 16:25:53, insgesamt 1-mal geändert.
Re: start und end offset von Zeichenkette xyz aus Binärdatei ausgeben
Ich glaube, ich bin noch dabei, dein Problem ueberhaupt zu verstehen ...
Es geht also *nicht* darum, einen fixen String zu suchen, sondern eine Bytefolge, von der nur der Anfang und das Ende bekannt sind. Die Bytefolge ist vermutlich kein String, sondern eine beliebige Bytesequenz. Gesucht ist die Position (Offset) von Anfang und Ende der Bytesequenz. -- Ist das so korrekt?
Was du also brauchst, ist ein Programm, das in der Binaerdatei eine gegebenen Anfangssequenz findet und deren Position ausgibt. Anschliessend muss von dieser Position ausgehend eine (die naechste?) Endsequenz gefunden werden und deren Position ausgegeben werden. -- Ist das so korrekt?
Sind die Anfangs- und Endsequenzen lesbare Strings, oder koennen die auch beliebige Bytes enthalten?
strings(1) kann man nur nutzen, wenn es eine Zeichenkette aus lesbaren Zeichen gewesen waere. grep(1) kann auch keine Newlines und Null-Bytes.
Es geht also *nicht* darum, einen fixen String zu suchen, sondern eine Bytefolge, von der nur der Anfang und das Ende bekannt sind. Die Bytefolge ist vermutlich kein String, sondern eine beliebige Bytesequenz. Gesucht ist die Position (Offset) von Anfang und Ende der Bytesequenz. -- Ist das so korrekt?
Was du also brauchst, ist ein Programm, das in der Binaerdatei eine gegebenen Anfangssequenz findet und deren Position ausgibt. Anschliessend muss von dieser Position ausgehend eine (die naechste?) Endsequenz gefunden werden und deren Position ausgegeben werden. -- Ist das so korrekt?
Sind die Anfangs- und Endsequenzen lesbare Strings, oder koennen die auch beliebige Bytes enthalten?
strings(1) kann man nur nutzen, wenn es eine Zeichenkette aus lesbaren Zeichen gewesen waere. grep(1) kann auch keine Newlines und Null-Bytes.
Use ed once in a while!
Re: start und end offset von Zeichenkette xyz aus Binärdatei ausgeben
Ich hab mal was programmiert:
Oben in die globalen Variablen die Start- und Ende-Strings eintragen (unter der Annahme, dass sie keine Null-Bytes enthaltne, sonst muss man den Code anpassen).
Gelesen wird von Stdin.
Ausgegeben wird dann der Beginn des Start-Strings und der Beginn des Ende-Strings in Bytes ab Dateianfang.
Ich habe nur wenig getestet und es koennen, gut moeglich Off-by-one-Fehler und aehnliches enthalten sein. Aber das ist mal ein Anfang.
Randfalltests und die Uebergabe der Start/Ende-Strings als Kommandozeilenparameter (nur falls es wirklich Strings sind), kann bei Gelegenheit ja jemand von euch beisteuern.
(Ich finde das Problem einfach spannend und hatte Lust ein bisschen C zu schreiben ...)
Code: Alles auswählen
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
char *start = "START";
char *end = "END";
unsigned long
findnext(FILE *file, char *search) {
char *cp = search;
int c;
off_t offset = 0;
while ((c = fgetc(file)) != EOF) {
if (c != *cp) {
continue;
}
offset = ftell(file);
while (*cp++) {
if ((c = fgetc(file)) == EOF) {
exit(1);
}
if (*cp && c != *cp) {
cp = search;
break;
}
if (!*cp) {
printf("`%s' found at %lu\n", search, offset);
return offset;
}
}
}
return 0;
}
int
main(void)
{
findnext(stdin, start);
findnext(stdin, end);
return 0;
}
Gelesen wird von Stdin.
Ausgegeben wird dann der Beginn des Start-Strings und der Beginn des Ende-Strings in Bytes ab Dateianfang.
Ich habe nur wenig getestet und es koennen, gut moeglich Off-by-one-Fehler und aehnliches enthalten sein. Aber das ist mal ein Anfang.
Randfalltests und die Uebergabe der Start/Ende-Strings als Kommandozeilenparameter (nur falls es wirklich Strings sind), kann bei Gelegenheit ja jemand von euch beisteuern.
(Ich finde das Problem einfach spannend und hatte Lust ein bisschen C zu schreiben ...)
Use ed once in a while!
Re: start und end offset von Zeichenkette xyz aus Binärdatei ausgeben
... nicht ganzIch glaube, ich bin noch dabei, dein Problem ueberhaupt zu verstehen ...
Es geht also *nicht* darum, einen fixen String zu suchen, sondern eine Bytefolge, von der nur der Anfang und das Ende bekannt sind. Die Bytefolge ist vermutlich kein String, sondern eine beliebige Bytesequenz. Gesucht ist die Position (Offset) von Anfang und Ende der Bytesequenz. -- Ist das so korrekt?
also ich ver(suche) den START OFFSET der Zeichenkette und den END OFFSET von der Gesamt- Zeichenkette in der Binärdatei zu ermitteln, wenn ich die beiden Werte habe kann ich mir die gesamte Zeichenketten ausgeben lassen, weil der Inhalt kann varieren aber nicht der Start und das Ende der gesamten Zeichenkette.
Also als Bsp.:
gesuchte Zeichenkette:
START_STRING <-- (gesucht wird der OFFSET)
unbekannter inhalt an strings
unbekannter inhalt an strings
unbekannter inhalt an strings
ENDE_STRING <-- (gesucht wird der OFFSET)
Wenn ich die beiden OFFSET Werte habe kann ich mir dann von START OFFSET bis END OFFSET als Hexdump ausgeben lassen, daraus bekomme ich auch die eigentliche Stringlänge und kann auch den Inhalt modifizieren .... und dann ... irgend wann später die modifizierten Zeichenkette in der Binärdatei ersetzen "dd of= seek= count= bs= conv=notrunc" ...
(O.o)(Ich finde das Problem einfach spannend und hatte Lust ein bisschen C zu schreiben ...)
Danke
Re: start und end offset von Zeichenkette xyz aus Binärdatei ausgeben
Suchst du die Position am Beginn von ``START_STRING'' und die Position am Ende von ``ENDE_STRING''? Also, willst du den gesamten unbekannten Inhalt inklusive oder exklusive der beiden Marker?ren22 hat geschrieben:07.12.2019 16:20:55also ich ver(suche) den START OFFSET der Zeichenkette und den END OFFSET von der Gesamt- Zeichenkette in der Binärdatei zu ermitteln, wenn ich die beiden Werte habe kann ich mir die gesamte Zeichenketten ausgeben lassen, weil der Inhalt kann varieren aber nicht der Start und das Ende der gesamten Zeichenkette.
Also als Bsp.:
gesuchte Zeichenkette:
START_STRING <-- (gesucht wird der OFFSET)
unbekannter inhalt an strings
unbekannter inhalt an strings
unbekannter inhalt an strings
ENDE_STRING <-- (gesucht wird der OFFSET)
Mein Programm liefert derzeit jeweils den Beginn der Marker. Wenn du also zum Ende noch die Laenge des End-Markers hinzuzaehlst, dann hast du den gewuenschten Inhalt inklusive beider Marker.
Kannst du mein Programm mal ausprobieren? Sind deine Daten klein genug, um das mal schnell testen zu koennen?
Oder kannst du eine extrem zusammengekuerzte Test-Datei erzeugen, mit der ich testen koennte? Also am besten etwas, das auf eine Bildschirmseite passt.
Dann kannst du den Hexdump erzeugen und siehst dort dann ja schnell, ob die Marker ganz enthalten sind, oder ob vielleicht ein Off-by-one-Error dabei ist.
Solange niemand ein Programm kennt, das diese Funktionalitaet schon fertig bietet, koennen wir ja an meinem Programm weiterarbeiten.
Hier eine verbesserte Version (ein Off-by-one-Error beim Start-Offset beseitigt), die bereits den dd-Befehl zum Extrahieren des Abschnitts ausgibt:
Code: Alles auswählen
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
char *start = "START";
char *end = "END";
off_t
findnext(FILE *file, char *search) {
char *cp = search;
int c;
off_t offset = 0;
while ((c = fgetc(file)) != EOF) {
if (c != *cp) {
continue;
}
offset = ftell(file) - 1;
while (*cp++) {
if ((c = fgetc(file)) == EOF) {
exit(1);
}
if (*cp && c != *cp) {
cp = search;
break;
}
if (!*cp) {
return offset;
}
}
}
return 0;
}
int
main(void)
{
off_t soff=0, eoff=0;
soff = findnext(stdin, start);
if (soff == 0) {
fprintf(stderr, "Error: no start marker (%s) found\n", start);
return 0;
}
printf("start (%s) at %lu\n", start, soff);
eoff = findnext(stdin, end);
if (eoff == 0) {
fprintf(stderr, "Error: no end marker (%s) found\n", end);
return 0;
}
printf("end (%s) at %lu\n", end, eoff + strlen(end));
printf("extract section with: dd bs=1 skip=%lu count=%lu\n",
soff, (eoff+strlen(end))-soff);
return 0;
}
Use ed once in a while!
Re: start und end offset von Zeichenkette xyz aus Binärdatei ausgeben
Danke für deine Mühe aber ich kein leider kein C Programmieren und ich gerne unabhängig bleiben möchte, bleiben mir nur die üblichen Linux Verdächtigen auf der Kommandozeile.
Meine Lösung ist zwar nicht perfekt aber sie funktioniert soweit erstmal.
zuerste suche ich mittels grep nach drei Strings/Zeichenketten (den ersten string,den darauf folgenden string und den letzen string)
und pipe das an awk weiter, wobei awk wiederum prüft ob erstes pattern1=string1,dann prüfen ob pattern2=string2 direkt folgt nach dem ersten pattern1 und dann solange alle strings einlesen bis awk den dritten string mittels pattern3=string3 match'd ... die gesamte Ausgabe landet dabei direkt in einer Variable ...
*code Auszug vom bashscript"
$1="foo\|bar\|ende"
$FILE_OPT="DieHDDImageDatei.img"
... dann kann ich die Werte aus der Variable gut weiterverarbeiten mit einer readline schleife:
und erhalte den START und END OFFSET ....
vielen Dank an alle
Meine Lösung ist zwar nicht perfekt aber sie funktioniert soweit erstmal.
zuerste suche ich mittels grep nach drei Strings/Zeichenketten (den ersten string,den darauf folgenden string und den letzen string)
und pipe das an awk weiter, wobei awk wiederum prüft ob erstes pattern1=string1,dann prüfen ob pattern2=string2 direkt folgt nach dem ersten pattern1 und dann solange alle strings einlesen bis awk den dritten string mittels pattern3=string3 match'd ... die gesamte Ausgabe landet dabei direkt in einer Variable ...
*code Auszug vom bashscript"
$1="foo\|bar\|ende"
$FILE_OPT="DieHDDImageDatei.img"
Code: Alles auswählen
SEARCHRESULT="$(grep -baro -e "$1" "$FILE_OPT" | awk '/'"$FIRSTLINE"'/{a=0;l1=$0;c=NR} (/'"$SECONDLINE"'/&&NR==(c+1)){a=1;next;} (/'"$LASTLINE"'/&&a==1){a=0;print l1;print} (a==1){print}')"
Code: Alles auswählen
i=0
while read line ; do
if [ $i -eq 0 ]; then
SEARCHRESULT_OFFSET_START="${line%:*}"
SEARCHRESULT_STRING_START="${line#*:}"
...
i=$(($i+1))
continue
elif [ $i -eq 1 ]; then
SEARCHRESULT_OFFSET_END="${line%:*}"
SEARCHRESULT_STRING_END="${line#*:}"
...
vielen Dank an alle