![]() |
DFM-Dateien verschlüsseln?
Es nervt mich ein bisschen, dass man mit einem Resourcen-Programm die nackten DFM-Dateien eines Delphi-Programms sehen kann.
Ist es irgendwie möglich diese Dateien zu verschlüsseln oder zu verfremden? |
AW: DFM-Dateien verschlüsseln?
hm... was genau kann man aus der dfm auslesen, was man nicht auch in dem Form anschauen kann wenn man die Anwendung gestartet hat?
|
AW: DFM-Dateien verschlüsseln?
Das Problem ist eigentlich weniger das Auslesen. Eher ist es u.a., dass man alles verändern kann.
Es soll Leute geben die verändern das Formular und Copyright und verticken das Programm anderweitig unter neuem Name/Logo weiter. |
AW: DFM-Dateien verschlüsseln?
Ich habe ein Programm, das verschlüsselt alle Resourcen in der EXE. Beim EXE-Start entschlüsselt die EXE ihre eigenen Resourcen wieder. Ist leider Firmen-Copyright. Keine PAS. Kann aber leicht nachprogrogammiert werden.
|
AW: DFM-Dateien verschlüsseln?
Es sind nicht die nackten DFM drin.
DFMs gibt es als Text (so wird die im Delphi angezeigt und aktuell auch in der Datei gespeichert, aber in der EXE wird die binäre Version gespeichert -> TReader/TWriter) Delphi-Ressource-Editoren übersetzen das natürlich. Man kann die DFM auch selber speichern und über einen TReader manuell die DFM laden, nachdem man sie vorher z.B. entschlüsselt hat und sie vorher verschlüsselt als RC_DATA in die EXE aufgenommen hat. Aber das ist auch egal, denn ich kann zur Laufzeit das sichtbare Formular auslesen und mit daraus eine neue DFM generieren. bzw. die gewünschten Werte aus der Form auslesen, wenn ich da ran kommen will. |
AW: DFM-Dateien verschlüsseln?
Ich könnte mir gut vorstellen, dass solch eine Exe bei vielen Virenprogrammen anschlägt.
|
AW: DFM-Dateien verschlüsseln?
Zitat:
|
AW: DFM-Dateien verschlüsseln?
Es ist nicht selbstverständlich, dass man Summe XYZ für ein Zertifikat ausgibt. Viele, auch ich, haben für solche Späte kein Geld.
Außerdem sind viele, ich ebenfalls eingeschlossen, keine Delphi-Profis und haben von Verschlüsselung Null Ahnung ;) |
AW: DFM-Dateien verschlüsseln?
Du kannst von den DFMs einen HASH generieren (AfterBuild), diesen nach dem Compileren in der EXE/Ressources speichern und bei Programmstart entsprechend reagieren, wenn jemand die DFM manipuliert.
Alternativ erstellst du den Copyright-Hinweis eben erst zur Laufzeit. Die Zertifikate machen das auch nicht viel anders. (außer dass man zusätzlich das Zertifikat noch online verifizieren kann) |
AW: DFM-Dateien verschlüsseln?
Zitat:
Zitat:
Edit ein kleiner Test lädt zwar meine DFM-Resource aber ich bekomme nur 2 Zeilen ausgegeben und die noch mit falschen Zeichen:
Delphi-Quellcode:
// DFM-Resource laden
function LoadTextFromResourceByName(ResourceName: string): string; var ResourceStream: TResourceStream; sl: TStringList; begin if (FindResource(hInstance, PChar(ResourceName), RT_RCDATA) <> 0) then begin ResourceStream := TResourceStream.Create(hInstance, ResourceName, RT_RCDATA); try sl := TStringList.Create; try sl.LoadFromStream(ResourceStream); Result := sl.Text; finally sl.Free; end; finally ResourceStream.Free; end; end; end; showmessage( LoadTextFromResourceByName('TForm1') ); |
AW: DFM-Dateien verschlüsseln?
Um meine Programme vor unerwünschter Änderung zu schützen, hab' ich mir 'nen AfterCompile-Experten gebaut.
Nach dem Kompilieren errechnet der die MD5-Checksumme der Exe und schreibt diese in die EXE hinein. Meine Programme erstellen beim Start die MD5-Checksumme der Exe und vergleichen diese mit der in die EXE geschriebenen. Gibt es eine Abweichung, beendet sie sich mit 'ner entsprechenden Fehlermeldung. |
AW: DFM-Dateien verschlüsseln?
Ihr habt alle so tolle Lösungen und ich habe Null Ahnung davon -.-'
Ich gehe stark davon aus, dass du nicht preisgibst wie das funktioniert oder? |
AW: DFM-Dateien verschlüsseln?
Es gibt hier irgendwo ein Tutorial, wie man 'nen Experten baut.
Zum Bilden einer MD5-Checksumme gibt es Komponenten und sicherlich hier im Forum und im www diverse Quelltexte. Man muss das nur kombinieren und eine eigene Lösung finden. Wenn alle die gleiche Lösung nutzen, gibt es sicherlich auch schnell jemanden, der diese Lösung umgehen kann. |
AW: DFM-Dateien verschlüsseln?
MD5-Summe bilden und all das ist kein Problem.
Würde aber glaube ich eher meine Lösung verwenden. Nur schaffe ich es gerade nicht die DFM-Resource korrekt auszulesen. Ich bekomme folgendes ausgelesen TPF0TForm5Form5Left (mit ein paar speziellen, komischen Zeichen drin die hier aber gelöscht werden) Code
Delphi-Quellcode:
function LoadTextFromResourceByName(ResourceName: string): string;
var ResourceStream: TResourceStream; sl: TStringList; begin if (FindResource(hInstance, PChar(ResourceName), RT_RCDATA) <> 0) then begin ResourceStream := TResourceStream.Create(hInstance, ResourceName, RT_RCDATA); try sl := TStringList.Create; try sl.LoadFromStream(ResourceStream); Result := sl.Text; finally sl.Free; end; finally ResourceStream.Free; end; end; end; ShowMessage( LoadTextFromResourceByName(Form5.ClassName) ); |
AW: DFM-Dateien verschlüsseln?
Zitat:
Delphi-Quellcode:
// DFM-Resource laden
function LoadTextFromResourceByName(ResourceName: string): string; var ResourceStream: TResourceStream; StringStream: TStringStream; begin if (FindResource(hInstance, PChar(ResourceName), RT_RCDATA) <> 0) then begin ResourceStream := TResourceStream.Create(hInstance, ResourceName, RT_RCDATA); try StringStream := TStringStream.Create; try ObjectBinaryToText(ResourceStream, StringStream); Result := StringStream.DataString; finally StringStream.Free; end; finally ResourceStream.Free; end; end; end; |
AW: DFM-Dateien verschlüsseln?
Zitat:
|
AW: DFM-Dateien verschlüsseln?
Es gab doch mal in MadExcept eine Möglichkeit, die Exe beim Programmstart auf Änderungen zu überprüfen. Gibt's das da noch?
|
AW: DFM-Dateien verschlüsseln?
---
|
AW: DFM-Dateien verschlüsseln?
Zitat:
...und die vielen gelborangeroten Warnhinweise beim Setup und Updaten sind dann auch weg. |
AW: DFM-Dateien verschlüsseln?
Wenn Du den MD5-Wert in die Exe schreibst, musst Du natürlich beim Prüfen alles von der Exe nehmen, mit Ausnahme der MD5-Cbhecksumme.
Also: Exe wird erstellt. MD5 wird berechnet. MD5 hinten an die Exe drangehangen. Exe wird also 16 Byte größer. MD5 prüfen: MD5 zur Exe abzüglich der letzten 16 Byte ermitteln. Übereinstimmung prüfen und entsprechend reagieren. |
AW: DFM-Dateien verschlüsseln?
Klingt kompliziert. Ich habe das jetzt anders aber schlechter gemacht. Funktioniert trotzdem.
|
AW: DFM-Dateien verschlüsseln?
Und wie hast du es gemacht? :roll:
|
AW: DFM-Dateien verschlüsseln?
Meine Methode ist überhauptnicht kompliziert.
Man nehme: 'nen FileStream und lese in den die EXE ein. Lasse die MD5-Checksumme erstellen. Gehe ans Ende des FileStreams. Schreibe die MD5-Checksumme. Die EXE wird dadurch um die 16 Byte der MD5-Checksumme "länger". Zum Prüfen: Man nehme: 'nen FileStream und lese in den die EXE ein. Lasse die MD5-Checksumme über den FileStream, abzüglich der letzten 16 Byte, erstellen. Lese die 16 Byte der EXE. Vergleiche diese 16 Byte mit der MD5-Checksumme. Bei Übereinstimmung ist alles ok, ansonsten halt beliebige Reaktion auf die Veränderung durchführen. |
AW: DFM-Dateien verschlüsseln?
![]() |
AW: DFM-Dateien verschlüsseln?
Zitat:
![]() ObjectTextToResource ![]() ObjectBinaryToText ObjectTextToBinary
Delphi-Quellcode:
Vorher aber natürlich das Laden der DFM unterbinden, siehe TCustomForm.Create .
Stream := TResourceStream.Create(...);
Form := TXyzForm.Create; Form.ReadComponent(Stream); Bzw. durch eine leere Dummy-Ressource ersetzen, dann darf aber nichts in OnCreate auf die Form zugeifen. Oder beim Create der TForm vorgaukeln es wäre im FormDesigner.
Delphi-Quellcode:
Ich weiß, Instance.Create ist eigentlich "falsch" und es müsste Class.Create heißen, aaaaaaaaaber ... siehe NewInstance :angle:
Form := TXyzForm(TXyzForm.NewInstance);
// csDesigned in Form setzen Form.Create(Self); // csDesigned in Form entfernen Form.ReadComponent(Stream); Form.OnCreate(Form); // OnCreate wurde vorher aber auch schon einmal im Create aufgerufen Und das Verschlüssen dann natürlich von außen. (eine zweite EXE im AfterBuild aufrufen, die das macht) ![]() Statt die Form selber zu laden/entschlüsseln, könnte man auch die Resource-APIs hooken, dort entschlüsseln und das Laden der DFM weiterhin ganz normal TForm erledigen lassen welches dabei die entschlüsselte Ressource bekommt. Weniger Aufwändiger ist nur das Hashen, statt dem Verschlüsseln. |
AW: DFM-Dateien verschlüsseln?
Es ist ja schön, dass sich da so viele Leute Gedanken darüber machen. Ok, einen MD5-Hash für die Exe zu erstellen um zu prüfen ob nichts verändert wurde (Lizenzumgehung oder was weiß ich) ist ja ok.
Aber @a.def: Schreibst du wirklich ein so tolles und einzigartiges Programm als das es sich lohnt das zu klauen und zu kopieren? Ich meine ich habe damit keine Erfahrung weil ich bisher immer nur Software für mich privat oder für unsere Firma entwickelt habe. Verkauft oder öffentlich zur Verfügung gestellt wurde da aber noch nichts. Aber muss man sich da wirklich Gedanken drum machen? Wenn jemand dein Programm wirklich knacken will und den Aufwand betreibt, die Ressourcen zu ändern, dann wird er bestimmt auch noch die MD5 Prüfung außer Betrieb nehmen (können). Nur meine Meinung. Kann natürlich alles ganz anders sein. |
AW: DFM-Dateien verschlüsseln?
Aus meiner Sicht ist das 'ne interessante Spielerei.
Ernsthaft benötigen tue ich das nicht. |
AW: DFM-Dateien verschlüsseln?
Es sei denn, die IDE verabschiedet sich weil sie die DFM Datei nicht mehr lesen kann. Dann wäre es vielleicht interessant wenn man das Formular direkt aus Quellcode erstellen koennte, dann eventuell auch mit Verschlüsselung
|
AW: DFM-Dateien verschlüsseln?
Zitat:
|
AW: DFM-Dateien verschlüsseln?
Aktuelle Delphi-Versionen bieten eine interessante Schnittstelle, mit der man nach dem Lesen der DFM noch weitere DFM-Resourcen auf das Form loslassen kann. Das wird z.B. in FMX zur Verwaltung der platform-spezifischen Eigenschaften eines Forms verwendet, ist aber keineswegs auf FMX beschränkt.
Es gibt zwei Herangehensweisen:
In diesem Beispiel verwende ich den override-Mechanismus, um eine (hier in Textform vorliegende) DFM-Beschreibung beim Laden in das Form zu injizieren. Da es sich hier faktisch um ein geerbtes Form handelt, müssen die Instanzen alle
Delphi-Quellcode:
sein. Durch ein temporär erstelltes vererbtes Form, das nicht in die Exe eingelinkt wird, kann man den verändeten DFM-Inhalt auch recht einfach herleiten.
inherited
Delphi-Quellcode:
Hier noch die Original-DFM als Text:
type
TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); protected procedure GetDeltaStreams(Proc: TGetStreamProc); override; end; const cDFM = 'inherited Form1: TForm1' + sLineBreak + ' Left = 0' + sLineBreak + ' Top = 0' + sLineBreak + ' Caption = ''Form1''' + sLineBreak + ' ClientHeight = 299' + sLineBreak + ' ClientWidth = 635' + sLineBreak + ' Color = clBtnFace' + sLineBreak + ' Font.Charset = DEFAULT_CHARSET' + sLineBreak + ' Font.Color = clWindowText' + sLineBreak + ' Font.Height = -11' + sLineBreak + ' Font.Name = ''Tahoma''' + sLineBreak + ' Font.Style = []' + sLineBreak + ' OldCreateOrder = False' + sLineBreak + ' PixelsPerInch = 96' + sLineBreak + ' TextHeight = 13' + sLineBreak + ' inherited Button1: TButton' + sLineBreak + ' Left = 392' + sLineBreak + ' Top = 48' + sLineBreak + ' Width = 75' + sLineBreak + ' Height = 25' + sLineBreak + ' Caption = ''Button1''' + sLineBreak + ' TabOrder = 0' + sLineBreak + ' OnClick = Button1Click' + sLineBreak + ' end' + sLineBreak + ' inherited Memo1: TMemo' + sLineBreak + ' Left = 392' + sLineBreak + ' Top = 168' + sLineBreak + ' Width = 185' + sLineBreak + ' Height = 89' + sLineBreak + ' Lines.Strings = (' + sLineBreak + ' ''Der Brite Richard Browning hat am ''' + sLineBreak + ' ''Rande der Technology, ''' + sLineBreak + ' ''Entertainment and Design ''' + sLineBreak + ' ''conference in Vancouver seinen ''' + sLineBreak + ' ''"Daedalus Suit" im Rahmen einer ''' + sLineBreak + ' ''Live-Demo vorgestellt. Der Anzug ''' + sLineBreak + ' ''besteht aus einem verst''#228''rkenden ''' + sLineBreak + ' ''Exoskelett, das mit sechs ''' + sLineBreak + ' ''D''#252''sentriebwerken best''#252''ckt ist. ''' + sLineBreak + ' ''Momentan taugt das Ganze f''#252''r eine ''' + sLineBreak + ' ''Flugdauer von bis zu 10 Minuten, ''' + sLineBreak + ' ''berichtet BBC online.'')' + sLineBreak + ' TabOrder = 1' + sLineBreak + ' end' + sLineBreak + 'end'; procedure TForm1.GetDeltaStreams(Proc: TGetStreamProc); var stream: TMemoryStream; strS: TStringStream; begin inherited; strS := TStringStream.Create(cDFM); try stream := TMemoryStream.Create; try ObjectTextToBinary(strS, stream); stream.Position := 0; Proc(stream); finally stream.Free; end; finally strS.Free; end; end;
Code:
object Form1: TForm1
Left = 0 Top = 0 Caption = 'Form1' ClientHeight = 299 ClientWidth = 635 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 object Button1: TButton Left = 40 Top = 24 Width = 75 Height = 25 Caption = 'Button1' TabOrder = 0 OnClick = Button1Click end object Memo1: TMemo Left = 40 Top = 55 Width = 185 Height = 89 TabOrder = 1 end end |
AW: DFM-Dateien verschlüsseln?
Das entwickelt sich zu einer schönen Übung sehe ich gerade.
Ich habe mittlerweile alles hinbekommen außer.. ich schaffe es nicht die Datei abzüglich der letzten 16 Bytes einzulesen. Ich bekomme nur Chinesisch :pale:
Delphi-Quellcode:
Alles andere klappt. Die letzten 32 Zeichen lese ich so aus
// Dateiinhalt:
// TESTTESTTEST_d0f980502943ec62a52e0a44280a5066 aFileStream := TFileStream.Create(sFile, fmOpenRead or fmShareDenyWrite); try // Get hash of the original file content without the hash we appended before aFileStream.Seek(32 * SizeOf(Char), soFromEnd); // gehe an die End-Position-32 Zeichen (also bis zum _) SetLength(s, aFileStream.Position * SizeOf(Char)); // setze die Länge von s auf Länge von "TESTTESTTEST_" aFileStream.Read(s[1], Length(s) * SizeOf(Char)); ShowMessage(s); // Chinesisch? finally aFileStream.Free; end;
Delphi-Quellcode:
SetLength(sOut, 32 * SizeOf(Char));
aFileStream.Position := aFileStream.Size - Length(sOut); aFileStream.Read(sOut[1], Length(sOut) * SizeOf(Char)); // sOut enthält nun d0f980502943ec62a52e0a44280a5066 |
AW: DFM-Dateien verschlüsseln?
Du weißt aber schon das unter XE8 SizeOf(Char) = 2 ist, oder?
Und wenn man einen Binären Inhalt in einen (Unicode) String liest kann (nach Betrachtung der Wahrscheinlichkeit) nur Chinesisch raus kommen. |
AW: DFM-Dateien verschlüsseln?
Das SizeOf(Char) 2 ist weiß ich. Aber wenn ich ich zum Auslesen 16*SizeOf(Char) verwende statt 32 bekomme ich ein falsches Ergebnis und nicht d0f980502943ec62a52e0a44280a5066
|
AW: DFM-Dateien verschlüsseln?
Ich würd' für die MD5-Checksumme kein Char sondern Byte nehmen.
|
AW: DFM-Dateien verschlüsseln?
Ich bin jetzt soweit, dass es funktioniert. Nur von Char auf Byte habe ich noch nicht umgestellt, da das irgendwie nicht klappt.
Delphi-Quellcode:
// Calculate the hash of a files content and append it to the file
aFileStream := TFileStream.Create(sFile, fmOpenReadWrite or fmShareDenyNone); try aFileStream.Position := 0; SetLength(s, aFileStream.Size); aFileStream.Read(s[1], Length(s)); // hash berechnen aFileStream.Position := aFileStream.Size; aFileStream.Write(s[1], Length(s) * SizeOf(Char)); finally aFileStream.Free; end;
Delphi-Quellcode:
aFileStream := TFileStream.Create(sFile, fmOpenRead or fmShareDenyWrite);
try // Get the hash of the original file content (without the hash we appended before) aFileStream.Position := 0; SetLength(s, aFileStream.Size - (32 * SizeOf(Char))); aFileStream.Read(s[1], Length(s)); // hash berechnen // Get hash from stream end SetLength(sOut, 32 * SizeOf(Char)); aFileStream.Position := aFileStream.Size - Length(sOut); aFileStream.Read(sOut[1], Length(sOut)); finally aFileStream.Free; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:07 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-2025 by Thomas Breitkreuz