Platzhalter in Programm1.exe mit Programm2.exe verändern

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Tracker
Beiträge: 53
Registriert: 22.11.2005 21:46
Computerausstattung: Intel Core 2 Quad Q6600, 2,4 GHZ, 2 GB RAM, NVidia GeForce 8600 GT 512 MB, Windows XP Prof. SP3, PureBasic v4.51

Platzhalter in Programm1.exe mit Programm2.exe verändern

Beitrag von Tracker »

Ich habe Kenntnisse in PowerBasic für DOS, VBA und VB6.
In PureBasic bin ich noch Anfänger.
Ich bin heute dem PureBoard-Forum beigetreten, weil ich ein Problem habe, in dem ich nicht weiterkomme. :(

Ich habe in der DataSection eines Musterprogramms Programm1.exe einen Platzhalterstring, den ich bei Bedarf mit Hilfe einer Programm2.exe ersetzen möchte.

Beispiel:

Code: Alles auswählen

;=== Start von Programm1.exe ===
Restore Platzhalter
Read Austauschtext$

MessageRequester("Programm1.exe",Austauschtext$,0)

DataSection
   Platzhalter:
   Data.s "Dieser Text soll von Programm2.exe ersetzt werden"
   PlatzhalterEnde:
EndDataSection
;=== Ende von Programm1.exe ===


;=== Start von Programm2.exe ===
Programm1$ = "Programm1.EXE"
If OpenFile(0,Programm1$)
   laenge = Lof()
   ;Programm1.exe komplett in den Speicher einlesen
   *MemoryID = AllocateMemory(laenge)
   If *MemoryID
      FileSeek(1)
      zeichen = ReadData(*MemoryID, laenge)
   EndIf   
   ;Austauschtext im Speicher suchen und ersetzen
   ;?????????????????????????????????????????????
   ;Wie muss der Code hier aussehen, um im Speicher 
   ;den gesuchten Platzhaltertext von Programm1.exe
   ;zu finden und zu ersetzen?
   ;Gibt es in PureBasic einen Befehl oder kennt 
   ;jemand einen PureBasic-Code, die das ermöglicht?
   ;?????????????????????????????????????????????
   ;Speicherbereich wieder in Programm1.exe speichern
   FileSeek(1)
   WriteData(*MemoryID,laenge)
   CloseFile(0) 
EndIf
;=== Ende von Programm2.exe ===
Ich kann die Programm1.exe wie eine Datei mit Programm2.exe öffnen und in den Speicher einlesen.

Nach Aktualisierung schreibe ich den veränderten Speicherbereich zurück in die Programm1.exe.

Gibt es in PureBasic einen Befehl, der den Platzhalterstring im Speicher findet und ihn durch einen anderen String ersetzt oder kennt jemand einen Code, der dies ermöglicht?

Ich habe im Forum und in Codebibliotheken anderer PureBasic-Seiten schon nachgesehen, aber noch keine passende Lösung gefunden.

Kennt jemand eine einfache Lösung, die dies ermöglicht?[/code]
Ein fehlerfreies Programm ist der Traum jedes Programmierers
Benutzeravatar
Laurin
Beiträge: 1639
Registriert: 23.09.2004 18:04
Wohnort: /dev/eth0

Beitrag von Laurin »

Wen ich das richtig verstanden habe, dann willst du einen bestimmten String in einer Exe verändern.
Der String an sich müsste unverschlüsselt in der Exe zu finden sein.
Von daher bietet es sich an, die Exe in kleineren Teilen in eine Stringvariable zu kopieren und diese mit FindString() oder ReplaceString() durchsuchen zu lassen.

Ist das in deinem Sinne oder suchst du eine Möglichkeit das nur mit Memory zu machen?
Now these points of data make a beautiful line.
And we're out of beta. We're releasing on time.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Mann kann den String doch ans Ende der Exe anhängen und dort auslesen. Einfach noch die länge anhängen und schon findet man den Text auch ohne Labels usw.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Tracker
Beiträge: 53
Registriert: 22.11.2005 21:46
Computerausstattung: Intel Core 2 Quad Q6600, 2,4 GHZ, 2 GB RAM, NVidia GeForce 8600 GT 512 MB, Windows XP Prof. SP3, PureBasic v4.51

Beitrag von Tracker »

@Laurin
Ja, ich will einen String im einer anderen EXE-Datei verändern.
Der Platzhalterstring liegt unverschlüsselt vor.
Er hat eine vorgegebene Länge und soll von einem String der gleichen Länge ersetzt werden, damit sich die Länge der EXE-Datei nicht ändert und später in der Programm1.exe DataSection noch funktioniert.

Mein Problem ist, wie finde ich die Startposition, ab der der String ersetzt werden muss.

Konstruktionen wie die folgende gehen in die Hose, weil PureBasic keinen String von ca. 50 KB Länge unterstützt, der zudem die binären Daten der ExeDatei enthalten soll.

So geht's leider nicht!

Code: Alles auswählen

ExeString$    = PeekS(*MemoryID, laenge)
SuchString$   = "Dieser Text soll von Programm2.exe ersetzt werden"
ErsatzString$ = "Leider funktioniert dieses Beispiel nicht        "
PokeS(*MemoryID,ExeString$,laenge)
dummy$ = ReplaceString(ExeString$,SuchString$,ErsatzString$,2,1)
Byteweises untersuchen der binären Daten nach der Startposition des Platzhalterstrings stelle ich mir mühsam, langsam und fehlerbehaftet vor.

Wenn es eine Funktion gäbe, die die Startposition des Platzhalterstrings zurückliefert, könnte ich auch den Programmteil bis zum Platzhalterstring in den Speicher einlesen, den Ersatzstring hinzufügen, den Rest der EXE-Datei ergänzen und den ganzen Speicherblock in die EXE-Datei zurückschreiben.

Ich weiß nur nicht wie!
Ob die Suchfunktion im Speicher sucht oder den String beim Einlesen der Programm1.exe ersetzt ist mir egal.
Ich suche nur eine einfache, sichere Lösung für das Probem.


@ts-soft
Ich will, dass ich später in der Programm1.exe die Befehle zu DataSection verwenden kann, weil ich anschließend noch ein Archiv an die EXE-Datei anhängen will. Dann würde der String doch wieder in der Mitte der Programm1.exe stehen. Für das Archiv habe ich jedoch bereits eine Lösung.

Ich könnte natürlich in der fertigen Programm1.exe manuell den Start des Platzhalterstrings ermitteln, notieren und in der Programm2.exe verwenden. Das wäre nur schlecht, falls ich Updates an der Programm1.exe vornehmen will und die Datei neu compilieren muss.

Kannst Du mir anhand eines Codebeispiels zeigen, wie du dir eine Lösung vorstellst?
Ein fehlerfreies Programm ist der Traum jedes Programmierers
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

>> Kannst Du mir anhand eines Codebeispiels zeigen, wie du dir eine Lösung vorstellst?
Auslesen durch:

Code: Alles auswählen

File = ReadFile(#PB_Any, "Programm.exe")
If File
  FileSeek(Lof()-4) ; Länge des Strings ermitteln, steht am ende der exe
  filelen.l = ReadLong()
  *mem = AllocateMemory(filelen)
  FileSeek(Lof()-4-filelen); Hier beginnt der String
  ReadData(*mem, filelen) ; in den Speicher damit
  CloseFile(File)
EndIf
Das funktioniert auch, wenn man auf sich selbst zugreift. Ändern geht allerdings nur von einem anderen Programm aus, wenn dieses nicht gestartet wurde.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Tracker
Beiträge: 53
Registriert: 22.11.2005 21:46
Computerausstattung: Intel Core 2 Quad Q6600, 2,4 GHZ, 2 GB RAM, NVidia GeForce 8600 GT 512 MB, Windows XP Prof. SP3, PureBasic v4.51

Beitrag von Tracker »

Vielen Dank für deinen Code.
Er hätte fast mein Problem gelöst, wenn ich nicht zusätzlich noch ein Archiv anhängen müsste.

Folgendes habe ich ausprobiert:

Code: Alles auswählen

;=== Start von Programm1.exe ===
File = ReadFile(#PB_Any, "Programm1.exe")
If File
   FileSeek(Lof()-4) 
   filelen.l = ReadLong()
   If filelen
      *mem = AllocateMemory(filelen)
      FileSeek(Lof()-4-filelen)
      ReadData(*mem, filelen)
      Teststring$ = PeekS(*mem, filelen)
   Else
      Teststring$ = "Es wurde noch kein String angehängt"
   EndIf
   CloseFile(File)
EndIf
MessageRequester("Angefügten String einlesen", Teststring$,0)
End
;=== Ende von Programm1.exe ===

Code: Alles auswählen

;=== Start von Programm2.exe ===
Teststring$ = "Dieser String wird an Programm1.exe angehängt"
filelen.l = Len(Teststring$)        
File = OpenFile(#PB_Any,"Programm1.exe")
If File
   FileSeek(Lof()+1) ;hinter Dateiende positionieren
   WriteString(Teststring$) ;Teststring anhängen
   WriteLong(filelen)       ;Stringlänge auch anhängen     
   CloseFile(File)
EndIf
End
;=== Ende von Programm2.exe ===
Zuerst muss eine Musterdatei Programm1.exe existieren, an die ein String und die Stringlänge angehängt werden soll.

Mit Programm2.exe hänge ich einen Teststring und die Stringlänge als Long-Wert (4 Bytes) an die Programm1.exe an.

Programm1.exe liest basierend auf deinem Code die Stringlänge aus der am Ende der Programm1.exe gespeicherten Long-Variable.
Mit diesem Wert kann die Position des Strings ausgehend vom Dateiende ermittelt und in den Speicher eingelesen werden.
Den Speicher kann ich mit PeekS in einer String-Variablen speichern und diese im Programm dann weiterverarbeiten.

Soweit klappt alles wunderbar.

Nun muss ich jedoch noch ein Archiv an die Programm1.exe anhängen.

Hänge ich zuerst das Archiv und dann den String an, kann das Archiv nicht geöffnet werden.

Wird erst der String und dann das Archiv angehängt, liegt der String wieder in der Dateimitte und ich habe keine Suchfunktion, um ihn zu finden.

Ich könnte höchstens versuchen, die Länge das Archivs vor dem Anhängen ebenfalls zu ermitteln und ausgehend vom Dateiende den Dateizeiger rückwärts positionieren, um die Long-Variable und somit die Info zum Extrahieren des Strings zu erhalten.

So könnte es gehen.
Danke für den guten Denkansatz und den Code!

Trotzdem nochmal die Frage:
Kennt jemand einen Code, mit der man Platzhalter-Texte in EXE-Dateien suchen und ersetzen kann bzw. eine Funktion, die solche Texte im Speicher suchen und ersetzen kann?

Irgendwie fehlt mir in PureBasic eine MemSearch- bzw. MemReplace-Funktion.
wäre das nicht mal was für ein künftiges PureBasic-Update?

Hat sonst noch jemand eine gute Idee?
Ein fehlerfreies Programm ist der Traum jedes Programmierers
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

> Hat sonst noch jemand eine gute Idee?

folgender Beitrag könnte für Dich interessant sein:

http://forums.purebasic.com/german/view ... 22&start=8

Grüße ... Kiffi
Benutzeravatar
Tracker
Beiträge: 53
Registriert: 22.11.2005 21:46
Computerausstattung: Intel Core 2 Quad Q6600, 2,4 GHZ, 2 GB RAM, NVidia GeForce 8600 GT 512 MB, Windows XP Prof. SP3, PureBasic v4.51

Beitrag von Tracker »

Danke für den Tipp!

Ich kenne den Code, kann ihn aber seit heute erst besser verstehen, seitden ts-soft mir den Tipp mit dem Anhängen eines Strings plus Stringlänge in einer Long-Variable gegeben hat.

Wenn ich den Code richtig interpretiere, enthält er aber auch keine Suchen- und Ersetzen-Funktion, sondern arbeitet ähnlich wie obiges Beispiel.

Er kann mir aber vielleicht helfen, mein Programm so abzusichern, dass ich es nicht mehrfach gleichzeitig starten kann.

Mischa schreibt wirklich tolle Programme.
Er hat ja auch die phantastische PackerEX geschieben, die ich als Include-Datei auch sehr gut gebrauchen kann.


Mittlerweile habe ich auf der deutschen PureArec.Net-Seite im Codearchiv auch eine Funktion ReplaceFileData.pb entdeckt
(Author: Froggerprogger, updated for PB3.92+ by Lars).

Sie ist folgendermaßen deklariert:

Code: Alles auswählen

Procedure.l ReplaceFileData(Filename.s, outputfilename.s, *searchdata.l, searchdataLen.l, *replacedata, replacedataLen.l)
Die Funktion scheint das zu leisten, was ich benötige.
Leider habe ich kein Beispiel, wie man die Funktion benutzt.

Welche Zeiger muss ich für *searchdata und *replacedata eingeben?
Sind das Zeiger auf die Strings, die als Long-Werte übergeben werden oder muss ich Speicher reservieren, die Strings einlesen und die Speicherblöcke übergeben.

Mit Zeigern und Speicherfunktionen habe ich noch große Verständnisschwierigkeiten.

Kann mir jemand ein kurzes Codebeispiel posten, wie man den Aufruf der Funktion vorbereitet und die Parameter richtig übergibt?
Ein fehlerfreies Programm ist der Traum jedes Programmierers
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Beitrag von Blackskyliner »

GUckmal in deinen Anderen Post, der auch so ähnlich ist :D da iss eigentlich ne passende antwort :)

[EDIT]
http://forums.purebasic.com/german/viewtopic.php?t=5751

den meinte ich :)
[/EDIT]
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
Tracker
Beiträge: 53
Registriert: 22.11.2005 21:46
Computerausstattung: Intel Core 2 Quad Q6600, 2,4 GHZ, 2 GB RAM, NVidia GeForce 8600 GT 512 MB, Windows XP Prof. SP3, PureBasic v4.51

Beitrag von Tracker »

@Blackskyliner
Der Link löst mein Problem leider nicht.
Ich werden den Ansatz mit der ReplaceFileData.pb weiter verfolgen und ausprobieren, ob sie das leistet, was sie soll und ob sie die beste Lösung darstellt.
Ein fehlerfreies Programm ist der Traum jedes Programmierers
Antworten