Laden...

Hex Dateien bearbeiten

Erstellt von Nisbo vor 8 Jahren Letzter Beitrag vor 8 Jahren 5.695 Views
N
Nisbo Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren
Hex Dateien bearbeiten

Servus,

ist es möglich mit C# Hex Dateien zu bearbeiten ?
Was ich machen möchte ist eine Hex Datei einlesen und einen Teil davon (0 bis 390) an die selbe Stelle einer 2. Hexdatei kopieren.

Geht darum die Programmierung der Kanäle eines Amateurfunkgerätes auf ein anderes Modell zu kopieren, also nichts illegales 😉

Habt ihr evtl ein paar Stichpunkte womit ich Google füttern kann ?

127 Beiträge seit 2015
vor 8 Jahren

Hmmm, jede Datei ist vom Grundsatz her Binär auf der Platte gespeichert.
Vom Grundsatz her kannst du also jede Datei Binär einlesen und auch Binär wieder schreiben.
Was du dazwischen machst, also zum Beispiel Binärwerte in Hexwerte umrechnen / darstellen und diese Werte verändern bleibt dabei komplett deiner Fantasie überlassen.
Um Dateien binär einzulesen hilft dir vermutlich der BinaryReader Class (System.IO)

Und zum Umrechnen von byte arrays in Hexwerte (wenn du das dann noch brauchst) kannst du Google bemühen. Hier ein Beispiel:
c# - How do you convert Byte Array to Hexadecimal String, and vice versa? - Stack Overflow

N
Nisbo Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren

Vielen dank, das war das was ich gesucht habe, das Auslesen klappt schon mal

        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
            openFileDialog2.ShowDialog();

            BinaryReader br = new BinaryReader(File.OpenRead(openFileDialog1.FileName));

            string eigeneConfig = null;
            for (int i = 0x00000; i <= 0x00032F; i++)
            {
                br.BaseStream.Position = i;
                eigeneConfig += br.ReadByte().ToString("X2");
            }
            br.Close();

            richTextBox1.Text = eigeneConfig;



            BinaryReader br2 = new BinaryReader(File.OpenRead(openFileDialog2.FileName));

            string vorlageConfig = null;
            for (int i = 0x00000; i <= 0x00032F; i++)
            {
                br2.BaseStream.Position = i;
                vorlageConfig += br2.ReadByte().ToString("X2");
            }
            br2.Close();

            richTextBox2.Text = vorlageConfig;

        }

lese gerade zum testen den selben Bereich in 2 RichTextBoxen ein

bei der 2. Box muss ich dann ja ab 330 lesen
for (int i = 0x00330; i ≤ ???????; i++)

nur wie sage ich dem Programm das es bis zum Ende der Datei lesen soll ?
ein br2.lenght gibt es nicht, schaut aber so aus als wenn die Dateien alle bis 0x12690A gehen

und dann muss ich ja noch die beiden Daten zusammen legen, macht man das mit nem String ?
Also dann eigeneConfig + vorlageConfig verketten um das dann so direkt wieder mit BinaryWriter zu schreiben ?

Naja egal das kann ich auch selber irgendwie testen wenn ich weiß wie ich bis zum Ende lese^^

T
17 Beiträge seit 2015
vor 8 Jahren

Laut BinaryReader.ReadByte-Methode fliegt am Ende eine EndofStreamException. Vielleicht so:


br.BaseStream.Position = 330;

try
{
     while(1)
     {
          Config += br.ReadByte().ToString();
     }
}
catch(EndofStreamException)
{

}

Keine Ahnung ob das sauber umgesetzt ist, sollte aber funktionieren.

Alternativ könnest du noch auf PeekChar prüfen. BinaryReader.PeekChar-Methode

N
Nisbo Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren

werde mir das mal angucken, momentan habe ich das mit dem festen Wert gelöst aber da gibts jetzt aber zwei Probleme

hier der Code fürs auslesen der 2. Datei

BinaryReader br2 = new BinaryReader(File.OpenRead(openFileDialog2.FileName));
            
            string vorlageConfig = null;
            for (int i = 0x00330; i <= 0x12690A; i++)
            {
                br2.BaseStream.Position = i;
                // vorlageConfig += br2.ReadByte().ToString("X2");
                zusammen += br2.ReadByte();
            }
            br2.Close();
            
            saveFileDialog1.ShowDialog();

            BinaryWriter bw = new BinaryWriter(File.OpenWrite(saveFileDialog1.FileName));
            bw.Write(zusammen);

            bw.Close();

Jetzt habe ich einmal das Problem das er wenn ich den Rest der 2. Datei (1,2 MB groß) auslese in den 60 Sekunden TimeOut geht so lange ich
** zusammen += br2.ReadByte();**
drin habe

Habe das dann mal auskommentiert um zu sehen ob er wenigstens richtig speichert und wollte halt nur den ersten Teil speichern aber da kommt dann was ganz anderes raus als in der Quelldatei
getestet mit
zusammen += br.ReadByte();
und
zusammen += br.ReadByte().ToString();

5.657 Beiträge seit 2006
vor 8 Jahren

Hi Nisbo,

ein br2.lenght gibt es nicht

Die Länge kannst du beim darunterliegenden Stream abfragen. Also erst einen FileStream erstellen, die Länge abfragen und damit einen BinaryReader erstellen. Oder stattdessen einfach die Länge der Datei auslesen.

** zusammen += br2.ReadByte();**

Das verkettet einfach die Zahlenwerte (0...255) miteinander zu einem String. Wenn du hexadezimale Werte benötigst, mußt du die entsprechende Formatierungsregel anwenden. Was du damit erreichen willst, ist mir immer noch nicht ganz klar. Aber es scheint sich hier wohl um ein Verständnisproblem zu handeln, was den Unterschied zwischen Textdateien und Binärdateien und die Darstellung als Hexadezimalwerte betrifft. Dazu sollten sich aber genügend Beispiele bei MSDN oder anderswo finden lassen.

Ansonsten empfehle ich dir, deinen Code mit dem Debugger zu überprüfen, und selbst zu schauen, an welchen Stellen nicht die erwarteten Werte berechnet werden: [Artikel] Debugger: Wie verwende ich den von Visual Studio?.

Christian

Weeks of programming can save you hours of planning

N
Nisbo Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren

Erklären wir es mal so an Hand von Automodellen, ich habe verschiedene Konfigurationsdateien für verschiedene Funkgeräte, der Hersteller war so clever diese nicht in einem "lesbaren" Format zu speichern. ^^

Diese Konfigurationsdateien funktionieren beim selben Modell untereinander, sprich
Radioeinstellungen beim VW Golf geht untereinander, also die Config von einem Golf geht in einem anderen Golf.

Will ich jetzt meinen Radioeinstellungen vom VW Golf in das Radio vom VW Polo einspielen dann akzeptiert die Programmiersoftware die Config nicht.

Um das zu Umgehen muss man der Programmiersoftware vortäuschen das es sich doch um einen Polo handelt. Diese Information stehen in der Config bis zum Offset 0x0032F

Ich kopiere jetzt also diese Information das es sich um einen Polo handelt aus der Config vom Polo an genau die Selbe Stelle der Config vom Golf und mache somit aus der Config vom Golf eine Config für den Polo.

Ich hoffe das war soweit verständlich worum es geht.

Im Hexeditor geht das ruck zuck, ich markiere die entsprechenden Zeilen, kopiere sie, markiere im anderen File die selbe Stelle, füge sie und und speicher die Datei.

Das Ganze will ich jetzt automatisch erledigen lassen da wir im Amateurfunkbereich auch Leute haben (meistens die schon etwas älteren so um die 60/70) welche mit sowas nicht mehr klar kommen. Aus dem Grund will ich ein kleines Programm basteln. Und natürlich auch für die eigene Faulheit ^^

Das verkettet einfach die Zahlenwerte (0...255) miteinander zu einem String. Wenn du hexadezimale Werte benötigst, mußt du die entsprechende Formatierungsregel anwenden.

ja das habe ich mir auch so gedacht nur halt keine Lösung ^^
Ich muss ja nur das was ich lese im selben Format wieder speichern und da stehe ich auf dem Schlauch, ein br2.WriteByte() gibt es nicht

5.657 Beiträge seit 2006
vor 8 Jahren

Wie hummigbird1 bereits sagte: Dateien liegen immer als Binärdaten vor. Ob du sie in einem Text-Editor oder in einem Hex-Editor bearbeitest ändert daran nichts. Es ist nur eine andere Darstellungsart der gleichen Daten. In deinem Code vermischst du aber alles, und daher kommt etwas anderes dabei heraus, als du dir wünschst. Wie gesagt, der Debugger würde dir dabei helfen, wenn du es mal ausprobierst.

ein br2.WriteByte() gibt es nicht

Deswegen heißt der BinaryReader auch BinaryReader. Was du suchst, ist der BinaryWriter.

Christian

PS: Wenn du vorhast, Bytes an einer bestimmten Stelle zu ändern, wäre es evtl. einfacher, die Daten mit File.ReadAllBytes in ein Array auszulesen, die Daten an der richtigen Stelle im Array zu ändern, und dann wieder in eine Datei zu schreiben.

Weeks of programming can save you hours of planning

N
Nisbo Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren

Ja den BinaryWriter habe ich ja schon eingebaut, mein Problem ist ja genau dort wo Du es erkannt hast ^^

In deinem Code vermischst du aber alles, und daher kommt etwas anderes dabei heraus, also du dir wünschst.

im Bezug auf

Wie gesagt, der Debugger würde dir dabei helfen, wenn du es mal ausprobierst.

muss ich dann wirklich mal versuchen mich damit zu beschäftigen, wird dann aber vermutlich wie immer bei mir eine Aufgabe des Projektes werden 😄 😄: D

PS: Wenn du vorhast, Bytes an einer bestimmten Stelle zu ändern, wäre es evtl. einfacher, die Daten mit  File.ReadAllBytes in ein Array auszulesen, die Daten an der richtigen Stelle im Array zu ändern, und dann wieder in eine Datei zu schreiben. 

Na ich will ja nicht nur ein paar Bytes ändern sondern ca 1 MB an Daten und zumindest klingt das so im Moment für mich komplizierter als das was ich mache

Auf jeden Fall erstmal danke für Deine Hilfe 😃

127 Beiträge seit 2015
vor 8 Jahren

Wieviel Daten du ändern willst ist egal, solange dein Arbeitsspeicher reicht ... bzw. die Datei nicht an die Grenzen des Prozessadressraums sprengt (ich glaube bei 32 bit waren das rund 2 GB +/- Management Overhead etc.)
Nachdem das gesagt ist, solange deine Configdatei nicht riesengroß ist kannst du sie wirklich komplett einlesen ... dann in dem eingelesen Array alle deine Änderungen (1 MB wenn es sein muß 😉) durchführen und dann das geänderte Array wieder als Binärdatei speichern und schon hast du was du willst.

N
Nisbo Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren

Habe leider keinerlei Ahnung wie ich das anstellen kann und will euch mit der Frage nicht auf den Keks gehen 😉

127 Beiträge seit 2015
vor 8 Jahren

Naja, du mußt uns ja auch nicht auf den Keks gehen denn es ist ja nicht so als ob das Internet nicht alle Antworten für dich schon bereithält:
c# - An elegant way to consume (all bytes of a) BinaryReader? - Stack Overflow

Da steht wie du eine komplette Datei als Byte Array einliest.
Und ich bin mir sicher das verändern und schreiben bekommst du auch hin wenn du dich ein wenig "umschaust"
Und wenn es doch mal partout nicht klappen sollte weil es doch mal etwas "komplizierter" wird dann darsft du uns gerne wieder "nerven", da wird dir dann niemand böse sein.

Es darf eben nur nicht der Eindruck entstehen das du andere die Arbeit machen läßt und du dich selbst nicht wirklich bemühst ...

Und wenn du es im Zweifelsfall doch von jemandem anderen lassen machen möchtest dann kannst du ja ein Gesuch ins passende Unterforum stellen: Jobbörse

N
Nisbo Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren

Da ich ja damit kein Geld verdienen will sondern anderen kostenlos helfen will werde ich wohl keine Projekte ausschreiben 😉

Werde mir das mit dem Array mal anschauen aber vermute jetzt mal schon das es beim schreiben wieder scheitern wird da es das falsche Format ist 😄 😄 😄

Ist halt gerade der Punkt wo es in viele verschiedene Richtung auseinander läuft, halt zu viele Problem auf einmal trotz der eigentlich guten Idee di eman hatte (zumindest in meinem Kopf) man traut sich nicht mehr zu fragen wegen genau diesem Punkt:

Es darf eben nur nicht der Eindruck entstehen das du andere die Arbeit machen läßt und du dich selbst nicht wirklich bemühst ...

Die geöffneten Browsetabs gehen in die "Millionen" und bei der Hälfte der Beiträge steht die selbe Frage ohne Antwort oder benutze google oder die Suchfunktion ^^

So jetzt versuche ich mal mich etwas hin zu legen, habe wieder Nachtschicht wo ich mich dann nebenbei um die Array Geschichte kümmern kann.

127 Beiträge seit 2015
vor 8 Jahren

Ein Projekt kannst du auch unentgeltlich ausschreiben und auf andere Art bezahlen:
Ein Kasten Bier, oder ein leckeres Steak oder sonst was ...

Ich fürchte du gehst die Sache einfach etwas zu "chaotisch" an.
Schritt-für-Schritt empfehle ich dir die komplexe Aufgabe anzugehen und Teilabschnitte zu lösen.
Schritte die ich sehe:

  1. Datei komplett einlesen. Ziel: Gesamte Datei als Byte Array ins Programm zu bekommen
  2. Dateiinhalt verändern: Ziel: Die entsprechenden Bytes im Byte Array sind so verändert wie du dir das vorstellst.
  3. Neue Datei schreiben: Ziel: Das Byte Array wird mitsamt den gemachten Änderungen wieder auf die Platte geschrieben.
    (Optional: 4. Probleme mit der neuen Datei analysieren und Lösungen finden. 😄 )

Also, ran an Schritt 1 und vergiss die anderen Sachen.
Sobald du Schritt 1 hast machst du genauso mit Schritt 2 etc. und am Ende hast du was du suchst.