Die eigene .exe Datei manipulieren

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Die eigene .exe Datei manipulieren

Beitrag von siro »

Einen schönen guten Morgen,

folgende Idee wollte ich gerne umsetzen:

Ein Programm in Lazarus hat nur einen "einzige" .exe Datei.
Wenn man dem Benutzer ermöglicht Einstellungen zu machen, wäre es natürlich sinnvoll diese auch abzuspeichern.
Einige Programme machen sowas in der Windows Registry oder in einer Konfigurationsdatei.

Zieht man mit dem Programm auf einen anderen Rechner um, MUSS man auch immer die Konfigurationsdatei mit schleppen.
Etwas in der Registry eintragen ist für mich ein absolutes tabu, das geht auf einem anderen Rechner dann garnicht mehr.

So hatte ich die Idee, einfach Werte in die eigene .exe Datei zu schreiben.

Dazu müsste ich einen Bereich innerhab der Datei haben, wo ich genau weis, WO meine Werte stehen.
Da dies jedoch nicht festgelegt werden kann, wo welcher Code steht, habe ich mir eine Identifizierung angelegt.
Diese gilt es nun in der Datei zu finden und dann weis ich, dahinter folgen meine speziellen Daten.

Beispiel:

const x:integer=1234;

Der Wert 1234 taucht irgendwo im Code auf und wenn ich weis wo, dann könnte ich den Wert in der .exe Datei entsprechend ändern.
So habe ich mir mal folgenden Code zusammengebaut, der auch wirklich funktioniert bis auf:

Ich darf meine eigene .exe nicht überschreiben !!!!! :cry:

So habe ich testweise erstmal eine Project2.exe Datei erzeugt um mein Vorgehen zu verifizieren.
Fazit: es funktioniert.

Es scheint aber so, dass das Betriebssystem es nicht zulässt die gestartete .exe zu manipulieren ????

Und genau da stellt sich die Frage an euch:

Wie kann ich dieses letzte "kleine" Problemchen lösen ?


Ich hab euch mal den Testcode hier reingepackt.
project1.zip
(128.83 KiB) 108-mal heruntergeladen
Das Programm Project1.exe wird gestartet.
Es erscheint in Caption die Anzahl der Programmstarts, also beim ersten mal eine 1
zudem wird eine Booleanwert ausgegeben ob es eine Erstbenutzung ist.
Und ein Name, der später verändert werden soll.

Mit dem Drücken des Buttons, wird die gesamte Project1.exe Datei in den Speicher eingelesen und an der "richtigen" Stelle im Speicher manipuliert
und dann wieder zurück auf Platte geschrieben.

!!!! Hinweis: ich schreibe eine Datei auf eure Festplatte, dies befindet sich dann im gleichem Verzeichnis,
zumindest bei mir mit Windows.

Da es "momentan" nicht möglich ist, es wieder Project1.exe zu nenen, wird momentan eine Project2.exe erzeugt
um das Vorgehen überhaupt zu verifizieren.

Die neu erstellte Project2.exe kann dann gestartet werden und man sieht, dass sich die Parameter korrekt verändert haben.

Welchen Trick kann ich anwenden, damit ich die Datei wieder Project1.exe nennen darf ? also dass sie sich selbst überschreibt ?

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Die eigene .exe Datei manipulieren

Beitrag von Socke »

siro hat geschrieben:
Di 30. Mär 2021, 09:33
Es scheint aber so, dass das Betriebssystem es nicht zulässt die gestartete .exe zu manipulieren ????

Und genau da stellt sich die Frage an euch:

Wie kann ich dieses letzte "kleine" Problemchen lösen ?
Ich glaube nicht, dass dieses Vorgehen eine gute Idee ist. Aber wenn du dein Problem so lösen möchtest, will ich deinen Virus nicht aufhalten ;-)

Windows sperrt aktuell ausgeführte exe-Dateien gegen Änderungen. Daher musst du den Umweg über eine zweites Programm gehen.
Du kannst alternativ deine "gepatchte" Exe-Datei in einem anderen Verzeichnis vorbereiten und dann mit dem nächsten Reboot austauschen (MoveFileExA, inuse.exe).
Solltest du deine gepatchte Version bereits vor einem Reboot starten wollen, kannst du bei Programmstart nach den dort abgelegten Versionen suchen und die neuste Version starten.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Die eigene .exe Datei manipulieren

Beitrag von siro »

Hallo Socke,
erstmal Danke für Deine Rückmeldung.

Das soll "auf keinen Fall" irgend welche anderen/zusätzlichen Aktiviäten hervorrufen, von wegen Booten, 2tes Programm oder ähnliches.

Das war eigentlich mehr eine Machbarkeitsstudie, die zwar prinzipell funktioniert, aber vom Betriebssystem leider so nicht zugelassen wird.

Dann gibt es auch keinen Sinn da weiter drüber zu diskutieren. Spass gemacht hat der Versuch aber dennoch....

Nicht jede Idee ist gut :)

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Die eigene .exe Datei manipulieren

Beitrag von mschnell »

Ganz schlechte Idee.
Früher hat man gerne ini Dateien gleichen namens neben die exe Datei in dasselbe Verzeichnis gelegt. Auch das ist heute absolut verpönt.
-Michael

Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: Die eigene .exe Datei manipulieren

Beitrag von six1 »

Ich erstelle ein Verzeichnis, in welchem ich die Exe ablege. Darunter gibt es dann wiederum ein Verzeichnis "Setup", in welchem ich eine Ini ablege. Wenn nötig, werden Inhalte in der Ini verschlüsselt.
Egal, wie das jemand findet; es ist sehr praktisch und ohne irgend welche Dateien suchen zu müssen, kann man einfach das ganze Projekt Verzeichnis kopieren und hat alles dabei.

Exakt so handhabe ich die Installationen von Lazarus.
Ein Basis Verzeichnis "LAZARUS_IDE" und darunter alle Versionen in eigenen Verzeichnissen.
Gruß, Michael

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Die eigene .exe Datei manipulieren

Beitrag von Warf »

Das ist ein Windows spezifisches verhalten und da ist auch so einfach kein weg drum rum. Was du machen kannst ist die änderung in einer temporären datei zu speichern, und dann in deinem OnClose oder OnDestroy event über den Befehlszeilenprozessor ein kleines script ausführen was wartet bis die Anwendung beendet ist (ein konstanter sleep von ein paar sekunden sollte reichen) und danach die exe durch die temporäre ersetzt. Sollte ein einzeiler sein den du über TProcess starten kannst kurz bevor dein program runter fährt.

Das gesagt, die Idee halte ich für nicht sehr durchdacht. Zu erst mal der Elephant im Raum, die meißten Virenschutzprogramme werden dein Programm schneller vom Rechner fegen als du gucken kannst, aber es gibt noch ein paar weitere Probleme:
1. Wie sollen updates funktionieren? Wenn du die exe updatest sind alle deine konfigurationen weg
2. Was wenn das pattern nach dem du suchst zufällig wo anders auftritt (evtl nicht mal bei dir im code sondern in einer lib die du statisch linkst)
3. Was wenn du das programm ohne konfigurationen weiter geben willst (z.B. bei nem mail clienten wenn du den weiter geben willst ohne unbedingt deinen email zugang mit zu geben)
4. Was wenn die konfiguration kaputt ist (z.B. durch einen bug ein falscher wert reingeschrieben wurde) und das programm nicht mehr startet, wie soll man die konfiguration resetten können?

Wenn das weitergeben des Programmes deine hauptmotivation ist, mach es doch so: Dein programm hat ein config verzeichnis in dem alle konfigs liegen. Außerdem fügst du einen Button hinzu der "Konfiguration Exportieren" oder so heißt, der deine ganze konfig einfach zipt und das zip ausspuckt. Dann kann ein anderer nutzer mittels "Konfiguration Importieren" dieses zip importieren.
Wenn du unbedingt das programm mit konfiguration weiter geben möchtest, kannst du die exe und die Konfiguration in ein sich selbst extrahierendes zip als installer packen, das ist eine .exe datei die du weiter geben kannst, die dann alles einrichtet.

PS: Mit der Idee von "einer exe" kommt man mMn. eh nicht sonderlich weit. Irgendwann benötigt man mal OpenGL, OpenSSL, oder irgendeine andere lib, und dann plötzlich muss man eh noch mehrere dlls mitliefern, die man separat up to date halten muss und benötigt einen installer der sich dann auch um solche sachen kümmern kann

Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: Die eigene .exe Datei manipulieren

Beitrag von six1 »

Man könnte es auch so machen:
1) Programm selbst umbenennen zur Laufzeit ( Name.exe -> Name_tmp.exe)
2) umbenanntes Programm unter ursprünglichem Namen kopieren (Name_tmp.exe -> Name.exe )
3) Programm verändern (changes Name.exe)
4) Bei Neustart des Programms Tmp Datei löschen (Del Name_tmp.exe)

Aber ich halte das auch für keinen guten Weg.
Gruß, Michael

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Die eigene .exe Datei manipulieren

Beitrag von siro »

Es ist ja doch noch Einiges an Information geflossen,
erst einmal Danke dafür.

@mschnell:
Meine Idee war wohl wirklich nicht so gut, das gestehe ich nun ein...

Eine Datei xxx.ini im Programmverzeichnis finde ich aber persönlich ganz okay.
Besser als wenn man noch irgednwo Dateien suchen muss, warum sollte das verpönt sein.
Das finde ich "wesentlich" besser als ständig die Registry zu "vergrößern"
Die hat man auf einem anderen Rechner ja eh nicht in gleicher Form zur Verfügung beim Programmtransport.

so wie Michael (six1) das schreibt.
Ein Ordner und entsprechende Unterordner ist praktisch. Ein Backup lediglich das Verzeichnis kopieren und fertig.
Das ist dann "ALLES" drin.

@warf
Du hast dort viele Punkte aufgeführt, die ich nun auch befürworten muss.
Ja, meine Idee hat tatsächlich das ein oder andere (oder alle :wink: ) von Dir beschriebene Probleme.
Mit Konfiguration Eport/Import ist natürlich auch eine SEHR schöne und einfache Methode.

Ich denke das Thema ist durch. Es gibt keinen Sinn den "selbstmodifizierenden" Code einzusetzen.
Früher hatte ich auch noch Checksummen über die gesamte Datei gebildet, auch die würde sich ja dann ändern...

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Die eigene .exe Datei manipulieren

Beitrag von PascalDragon »

siro hat geschrieben:
Di 30. Mär 2021, 17:16
Besser als wenn man noch irgednwo Dateien suchen muss, warum sollte das verpönt sein.
Weil es je nach Betriebssystem einfach bestimmte Orte für die Konfiguration gibt. Und dabei meine ich jetzt nicht mal die Registry. In Windows hast du einerseits das benutzerspezifische AppData Verzeichnis (z.B. C:\Users\<user>\AppData\Roaming\<app>) und dann das für alle Benutzer (z.B. C:\ProgramData\<app>), beide sind über entsprechend APIs abfragbar. Eine Konfigurationsdatei bei der Anwendung ist nur mit mehr Aufwand benutzerspezifisch zu bekommen. Unter Linux zum Beispiel ist es sogar mehr als verpönt Konfigurationsdateien bei der Anwendung zu haben. Dort hat alles seinen Platz, von der Binary über Anwendungsressourcen bis hin zu den Konfigurationsdateien.

Wenn du deine Anwendung portabel haben möchtest, dann biete doch dem Nutzer an seine Einstellungen zu exportieren und auf dem neuen Rechner wieder zu importieren. Oder erlaube es zusätzlich eine Konfiguration bei der Anwendung zu haben, wenn der Nutzer deine Anwendung zum Beispiel auf einem USB-Stick einrichtet.
FPC Compiler Entwickler

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Die eigene .exe Datei manipulieren

Beitrag von siro »

Ehrlich gesagt kenne ich den Ordner garnicht, :shock:
aber auch Dir nochmal Danke für die Info.

Wie ich sehe, haben da so einige Programme zusätzliche Daten abgelegt.
Das meinte ich mit "suchen" ich wär nie auf die Idee gekommen, dort überhaupt etwas zu suchen.
Eigentlich möchte ich garnicht suchen.

Ich hab aber mit der "C" Programmierung schon so etliches an Dateien gesucht und mein unverzichtbares Tool ist seither
"Everything" Das beste/schnellste was ich kenne um Dateien zu finden.

Siro

Grad mal einen Versuch gemacht:

Code: Alles auswählen

ChDir('c:\Benutzer');
und schon hat man die ersten Probleme....
Im Explorer heisst der Ordner aber so....

Aber bitte keine Diskussion darüber. Ich kann halt mit der Windows Dateistruktur absolut nix anfangen. :roll:

Fazit für mich: Der Projektordner ist der beste Ort für Konfigurationsdateien, die sind ja nunmal auch zugehörig.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Die eigene .exe Datei manipulieren

Beitrag von Timm Thaler »

siro hat geschrieben:
Mi 31. Mär 2021, 15:16
Fazit für mich: Der Projektordner ist der beste Ort für Konfigurationsdateien, die sind ja nunmal auch zugehörig.
Nö, sind sie spätestens seit Multiuser nicht. Oder soll jeder User die gleichen Einstellungen eines Programms verwenden?

Und jahrelang hat man Win vorgeworfen unsicher zu sein. Dann verhindern sie, dass Dateien im Programmverzeichnis verändert werden können - ist es auch wieder nicht richtig.

Unter Linux geht das auch nicht, der "normale" User darf nix im root rumschreiben. Ja, leider ist es unter Linux nicht besser als unter Windows, die .meineConfig-Orgie im home hasse ich, wenn jedes Programm da seinen Müll reinkübelt.

Aber zumindest Lazarus bietet Dir sehr komfortabel mit GetAppConfigDir() die Konfig im richtigen Ordner zu sichern und zu laden, unabhängig vom OS. Da musst Du Dich auch nicht drum kümmern, ob das unter c:\Benutzer oder c:\Users steht.

Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: Die eigene .exe Datei manipulieren

Beitrag von six1 »

Naja, kommt immer auf die speziellen Umstände drauf an.
Ich habe meist nur ein allgemeines Setup, um die Datenverbindung über SSH Tunnel herzustellen.
Danach werden alle personalisierten Einstellungen aus der DB geholt.
Insofern kann eine Setup Datei im Ordner oder Unterordner des ausführbaren Programm schon Sinn ergeben; muss es aber nicht.

Dies kann bei Anderen ganz anders aussehen....
Gruß, Michael

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Die eigene .exe Datei manipulieren

Beitrag von af0815 »

Ich habe sowas als standard bei mir. Ist eine an und für sich leeres Datenmodul mit folgenden Code

Code: Alles auswählen

unit DMlocalData;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil;

type

  { TDMlocal }

  TDMlocal = class(TDataModule)
    procedure DataModuleCreate(Sender: TObject);
  private
    FExeFileName: String;
    FVersionStr : String;
    FBaseFileName : String;
    FBaseFilePath : String;
    FAppFileCfgName : String;
    FPropStorageName : String;
    function GetPropStorageName: String;
  protected
    procedure DoInit;
  public
    property AppFileCfgName : String read FAppFileCfgName;
    property BaseFileName : String read FBaseFileName;
    property BaseFilePath : String read FBaseFilePath;
    property ExeFileName : String read FExeFileName;
    property PropStorageName : String read GetPropStorageName;
    property VersionStr  : String read FVersionStr;
  end;

  function GetLocaldata:TDMlocal;

implementation

uses
    fileinfo
  , winpeimagereader
//  , LazLogger
  , LazFileUtils
  ;

var
  DMlocal: TDMlocal;

function GetLocaldata: TDMlocal;
begin
  if not Assigned(DMlocal) then
    DMlocal := TDMlocal.Create(nil);
  Result := DMlocal;
end;


{$R *.lfm}

{ TDMlocal }

procedure TDMlocal.DataModuleCreate(Sender: TObject);
begin
  FExeFileName := paramstr(0);
  DoInit;
end;

function TDMlocal.GetPropStorageName: String;
begin
  Result := FPropStorageName;
end;

procedure TDMlocal.DoInit;
var
  FileVerInfo:TFileVersionInfo;
begin
  FBaseFileName:= ExtractFileName(FExeFileName);
//  DebugLn('BaseFileName: ', FBaseFileName);
  FBaseFilePath:= ExtractFilePath(FExeFileName);
//  DebugLn('BaseFilePath: ', FBaseFilePath);
  FAppFileCfgName:= LazFileUtils.GetAppConfigFileUTF8(False, False, True);
//  DebugLn('AppFileCfgName: ', FAppFileCfgName);
  FPropStorageName:= ChangeFileExt(FAppFileCfgName,'.xml'); ;
//  DebugLn('PropStorageName: ', FPropStorageName);
  // Enable in project opions the 'Version Info' !!!
  FileVerInfo:= TFileVersionInfo.Create(nil);
  try
    FileVerInfo.FileName:= FExeFileName;
    // Wenn es hier kracht, einmal ansehen ob die Versionsinfos
    //   in den Einstellungen aktiviert sind
    FileVerInfo.ReadFileInfo;
    //DebugLn('Company: ',FileVerInfo.VersionStrings.Values['CompanyName']);
    //DebugLn('File description: ',FileVerInfo.VersionStrings.Values['FileDescription']);
    //DebugLn('File version: ',FileVerInfo.VersionStrings.Values['FileVersion']);
    //DebugLn('Internal name: ',FileVerInfo.VersionStrings.Values['InternalName']);
    //DebugLn('Legal copyright: ',FileVerInfo.VersionStrings.Values['LegalCopyright']);
    //DebugLn('Original filename: ',FileVerInfo.VersionStrings.Values['OriginalFilename']);
    //DebugLn('Product name: ',FileVerInfo.VersionStrings.Values['ProductName']);
    //DebugLn('Product version: ',FileVerInfo.VersionStrings.Values['ProductVersion']);
    FVersionStr := FileVerInfo.VersionStrings.Values['FileDescription']
                  + ' V'+ FileVerInfo.VersionStrings.Values['FileVersion'];
  finally
    FileVerInfo.Free;
  end;

end;

finalization
  if Assigned(DMlocal) then
    FreeAndNil(DMlocal);


end.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Die eigene .exe Datei manipulieren

Beitrag von PascalDragon »

siro hat geschrieben:
Mi 31. Mär 2021, 15:16
Grad mal einen Versuch gemacht:

Code: Alles auswählen

ChDir('c:\Benutzer');
und schon hat man die ersten Probleme....
Im Explorer heisst der Ordner aber so....
Es heißt aber auch nur im Explorer so. Der richtige Ordner heißt Users, kann aber theoretisch auch ganz wo anders liegen, deswegen sollst du ja auch die passende API Funktion dafür nehmen. Im Fall von FPC ist das GetAppConfigDir mit dem Global-Parameter auf False gesetzt.
FPC Compiler Entwickler

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Die eigene .exe Datei manipulieren

Beitrag von siro »

Grade ausprobiert:

Code: Alles auswählen

  caption:=GetAppConfigDir(TRUE);   // liefert C:\ProgramData\KEL103_V4\
  caption:=GetAppConfigDir(FALSE);  // liefert C:\Users\[mein Name]\AppData\Local\KEL103_V4\
Diese Verzeichnisse existieren aber noch nicht, die muss dann dort anscheinend selbst erst anlegen.

Danke Dir,
damit dürfte das auch wieder Plattformübergreifend funktionieren.

Siro
Zuletzt geändert von siro am Do 1. Apr 2021, 10:02, insgesamt 1-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Antworten