![]() |
Delphi-Version: XE2
Aus Anwendung heraus '.exe' mit ResourceString bearbeiten
Hallo, ich zerbreche mir schon den ganzen Tag den Kopf an einem Problem. Ich möchte bestimmt Info's in einer Exe speichern.
![]()
Delphi-Quellcode:
Das schreiben geht Problemlos, aber wenn ich die gepatchte Exe starte, bekomme ich kein Rückgabewert :/
//Aufruf
filename := ExtractFilePath(paramstr(0))+'patched'+ExtractFileName(paramstr(0)); PatchFile(Paramstr(0), filename, 'Version', '1.0.0.1'); // eigentlich blödes Beispielt mit der Versionsnummer //Code procedure PatchFile(const sourcefilename, destfilename: string; const globalident, newconfigstr: Ansistring); var exedata, magicword: Ansistring; p: Integer; pchecksum: PCardinal; begin MAGIC_WORD_LEN := Length(globalident); //globalconfigdata ist global deklariert. Schaut euch das Original an, dann ergiebt die nächste zeile Sinn globalconfigdata := #0#0#0#0 + globalident + #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 + #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0; // verhindern, dass die neuen Konfigdaten zu lang werden if Length(newconfigstr) > Length(globalconfigdata) - MAGIC_WORD_LEN - CHECKSUM_LEN then raise Exception.Create('Config String too long'); magicword := GetMagicWord; // raise Exception.Create(magicword); exedata := FileToString(sourcefilename); // Exe-Datei als String laden p := Pos(magicword, exedata); // Magisches Wort suchen Assert(p <> 0); pchecksum := PCardinal(@exedata[p]); Dec(pchecksum); Inc(p, MAGIC_WORD_LEN); // Magisches Wort überspringen // Configdaten überschreiben Move(newconfigstr[1], exedata[p], Length(newconfigstr)); pchecksum^ := CalcXorSum(exedata); // modifizierte EXE speichern StringToFile(destfilename, exedata); end; [EDIT] Natürlich habe ich auch die GetConfigString umgeschrieben:
Delphi-Quellcode:
//Auruf
Edit1.text := GetConfigString('Version'); //Code function GetConfigString(globalident: string): string; begin MAGIC_WORD_LEN := Length(globalident); globalconfigdata := #0#0#0#0 + globalident + #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 + #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0; Result := Copy(globalconfigdata, CHECKSUM_LEN + MAGIC_WORD_LEN + 1, 999); end; |
AW: Aus Anwendung heraus '.exe' mit ResourceString bearbeiten
Zitat:
Eine sehr saubere und durchaus Variable Lösung stellt dir das PE Format selbst in Form von Resourcen zur Verfügung. Die Windows API beinhaltet mehrere Methoden zur Manipulation von Resourcen. ![]() ![]() ![]() Die eigentlichen Daten würde ich dir der Einfachheit halber vorschlagen in einem packed record abzulegen. Hierbei musst du beachten, dass du Strings als ShortStrings mit bestimmter Länge deklarierst oder direkt nullterminierte Arrays verwendest.
Delphi-Quellcode:
Wenn du es noch variabler halten willst, würde ich mit einem MemoryStream arbeiten, über den du dann die ordinalen Typen direkt schreibst und bei Strings einfach die Länge vorwegstellst. So mache ich es bei meinem Netzwerkprotokoll, allerdings auch nur um Traffic zu sparen. Solange dir die Größe egal ist, kannst du theoretisch auch ein Array mit großzügig gewählter fixer Länge verwenden. Ist dein String dann kürzer, fügst du einfach ein Null-Char hinzu und behandelst das Array wie einen PChar.
type
MyData = packed record Value1: Integer; Value2: array[0..STR_LEN1] of Char; Value3: Single; end; |
AW: Aus Anwendung heraus '.exe' mit ResourceString bearbeiten
Liste der Anhänge anzeigen (Anzahl: 1)
Habe aus Langeweile mal eine kleine Demo gebastelt (vollständiger Code & Kompilat im Anhang).
Delphi-Quellcode:
TdxDataContainer ist eine kleine Klasse von mir, welche 2 abstrakte Methoden LoadFromStream() und SaveToStream() enthält, die in jeder Unterklasse implementiert werden müssen.
type
TResourceDataClass = class of TResourceData; TResourceData = class(TdxDataContainer) end; Folgende Funktion wird zum Schreiben der Daten verwendet:
Delphi-Quellcode:
Das Auslesen funktioniert folgendermaßen:
function WriteResource(Filename: String; lpName: PChar; lpType: PChar;
wLanguage: Word; ResourceData: TResourceData): Boolean; var MS: TMemoryStream; hUpdate: THandle; begin Result := false; MS := TMemoryStream.Create; try ResourceData.SaveToStream(MS); MS.Position := 0; hUpdate := BeginUpdateResource(PChar(Filename), false); if (hUpdate <> 0) and (hUpdate <> INVALID_HANDLE_VALUE) then try Result := UpdateResource(hUpdate, lpType, lpName, wLanguage, MS.Memory, MS.Size); finally Result := Result and EndUpdateResource(hUpdate, false); end; finally MS.Free; end; end;
Delphi-Quellcode:
function ReadResource(hInstance: HINST; lpName: PChar; lpType: PChar;
ResourceDataClass: TResourceDataClass): TResourceData; var RS: TResourceStream; begin Result := nil; if not ResourceExists(hInstance, lpName, lpType) then Exit; RS := TResourceStream.Create(hInstance, lpName, lpType); try RS.Position := 0; Result := ResourceDataClass.Create; Result.LoadFromStream(RS); finally RS.Free; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz