Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [BCB] Die nervigen Exporte in erzeugten Programmen (https://www.delphipraxis.net/112329-%5Bbcb%5D-die-nervigen-exporte-erzeugten-programmen.html)

Olli 18. Apr 2008 20:23


[BCB] Die nervigen Exporte in erzeugten Programmen
 
Moin,

gibt es eine Methode um ohne externe Tools (i.e. nur BCB6) die Exporte in den mit BCB erzeugten Binaerdateien zu verhindern. Ich habe diese nervige Angewohnheit von BCB6 erst kuerzlich bemerkt, kann es ihm aber auch nicht abgewoehnen.

Auch gibt es noch eine andere nervige Sache. Aus mir unbekanntem Grund benutzt eines der Kompilate SHDOCVW.OCX, obwohl der Code nichts dergleichen referenziert. Da ist das Smartlinking wohl nicht so smart wie zu erwarten, oder uebersehe ich etwas?

DMW 18. Apr 2008 21:38

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Zitat:

Zitat von Olli
gibt es eine Methode um ohne externe Tools (i.e. nur BCB6) die Exporte in den mit BCB erzeugten Binaerdateien zu verhindern. Ich habe diese nervige Angewohnheit von BCB6 erst kuerzlich bemerkt, kann es ihm aber auch nicht abgewoehnen.

Was das __CPPDebugHook-Symbol angeht, so kannst du es loswerden, indem du die Export-Definition in $(BCB)\Source\Rtl\Source\startup\c0nt.asm auskommentierst (auch die weiter unten in der Datei zu findende Referenzierung muß beseitigt werden) und die C++-RTL kompilierst. Daß die Übersetzung irgendwann mit einem Fehler abbricht, sollte nicht stören, da die Startup-Objektdateien zu diesem Zeitpunkt bereits übersetzt sind und Fehler lediglich in für den Debug-Modus kompilierten Dateien auftreten sollten, die den Code referenzieren. Allerdings solltest du eine Debug-Version der c0*.obj-Dateien behalten, die das Symbol exportieren. Eine Möglichkeit ist, die vorhandenen Dateien nach $(BCB)\Lib\Debug zu verschieben und die angepaßten Versionen in $(BCB)\Lib\Release unterzubringen, doch mußt du dann für Debug- und Release-Build die Projektoptionen entsprechend anpassen. (In C++Builder 2006 und höher gibt es dafür endlich die Build-Konfigurationen.) Ähnliches Vorgehen dürfte auch für _GetExceptDLLinfo möglich sein, jedoch habe ich das noch nicht getestet.

Die Initialize- und Finalize-Symbole für deine Units kannst du loswerden, wenn du #pragma package(smart_init) entfernst (alle Konsequenzen für die Initialisierung statischer Daten und für Packages sind in der Hilfe zu #pragma package dokumentiert). Symbole wie _MyForm, die davon herrühren, daß C++Builder standardmäßig eine globale Variable und Instanz für jedes Formular erzeugt, kannst du in den jeweiligen Headerdateien entfernen (die Zeile extern PACKAGE TMyForm *MyForm;).

Ein QC-Eintrag zum Thema wäre hier zu finden.


Zitat:

Zitat von Olli
Auch gibt es noch eine andere nervige Sache. Aus mir unbekanntem Grund benutzt eines der Kompilate SHDOCVW.OCX, obwohl der Code nichts dergleichen referenziert. Da ist das Smartlinking wohl nicht so smart wie zu erwarten, oder uebersehe ich etwas?

Vielleicht hilft es, in den Projektoptionen die Liste der Packages zu leeren oder zu optimieren.
Ansonsten: ist tatsächlich nirgendwo im Code ein #include "SHDocVw_OCX.h" oder ein #pragma link "SHDocVw_OCX" zurückgeblieben?

Bernhard Geyer 18. Apr 2008 22:05

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Zitat:

Zitat von Olli
Auch gibt es noch eine andere nervige Sache. Aus mir unbekanntem Grund benutzt eines der Kompilate SHDOCVW.OCX, obwohl der Code nichts dergleichen referenziert. Da ist das Smartlinking wohl nicht so smart wie zu erwarten, oder uebersehe ich etwas?

Ich weis jetzt nicht ob es bei "normalen" Programmen auch die Shdocvw.ocx ist, aber der IE (und seine Bestandteile) funken bei aktuellen Windows-Versionen überall rein. Es reicht schon wenn man einen Open/Save-Dialog verwendet das entsprechende IE-DLL's/OCX geladen werden (die z.B. bei Verwendung des Adobe SVG-Viewers zu komischen Seiteneffekten führen).

Olli 18. Apr 2008 22:31

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Erstmal danke an euch beide, fuer die Antworten.

Zitat:

Zitat von DMW
Was das __CPPDebugHook-Symbol angeht, so kannst du es loswerden, indem du die Export-Definition in $(BCB)\Source\Rtl\Source\startup\c0nt.asm auskommentierst (auch die weiter unten in der Datei zu findende Referenzierung muß beseitigt werden) und die C++-RTL kompilierst. Daß die Übersetzung irgendwann mit einem Fehler abbricht, sollte nicht stören, da die Startup-Objektdateien zu diesem Zeitpunkt bereits übersetzt sind und Fehler lediglich in für den Debug-Modus kompilierten Dateien auftreten sollten, die den Code referenzieren. Allerdings solltest du eine Debug-Version der c0*.obj-Dateien behalten, die das Symbol exportieren. Eine Möglichkeit ist, die vorhandenen Dateien nach $(BCB)\Lib\Debug zu verschieben und die angepaßten Versionen in $(BCB)\Lib\Release unterzubringen, doch mußt du dann für Debug- und Release-Build die Projektoptionen entsprechend anpassen. (In C++Builder 2006 und höher gibt es dafür endlich die Build-Konfigurationen.) Ähnliches Vorgehen dürfte auch für _GetExceptDLLinfo möglich sein, jedoch habe ich das noch nicht getestet.

Danke erstmal fuer die Erklaerung. Somit scheint es zumindest keine wirklich vernuenftige Methode zu geben, wie man es in der Standardkonfiguration hinbekommt. Ich neige zu einem "Typisch Borland ..." :|

Zitat:

Zitat von DMW
Die Initialize- und Finalize-Symbole für deine Units kannst du loswerden, wenn du #pragma package(smart_init) entfernst (alle Konsequenzen für die Initialisierung statischer Daten und für Packages sind in der Hilfe zu #pragma package dokumentiert). Symbole wie _MyForm, die davon herrühren, daß C++Builder standardmäßig eine globale Variable und Instanz für jedes Formular erzeugt, kannst du in den jeweiligen Headerdateien entfernen (die Zeile extern PACKAGE TMyForm *MyForm;).

Das ist wunderbar, funzt dann aber logischerweise nur an einigen Stellen.

Zitat:

Zitat von DMW
Ein QC-Eintrag zum Thema wäre hier zu finden.

Derjenige welcher den Bug gemeldet hat, wurde ja ziemlich abgebuegelt. Scheint, als haette der Entwickler von Borland noch nie was von Crackern gehoert. Die freuen sich ueber jeden Export mit Namen. Das ist defacto ein gutes Argument gegen BCB, immerhin hat Delphi nicht das Problem. Auch habe ich den Verdacht, dass allein durch die Exporte das Smartlinking beeintraechtigt wird, da logischerweise ein Export nicht wegoptimiert werden kann. Aber das ist nur ein Verdacht.


Zitat:

Zitat von DMW
Vielleicht hilft es, in den Projektoptionen die Liste der Packages zu leeren oder zu optimieren.
Ansonsten: ist tatsächlich nirgendwo im Code ein #include "SHDocVw_OCX.h" oder ein #pragma link "SHDocVw_OCX" zurückgeblieben?

Also ich habe durch den gesamten Projektcode gegreppt: Nix. Dann habe ich sicherheitshalber nochmal die SoftGems-Komponenten und die madCollection gegreppt und da kam auch nix dergleichen raus (der eine Treffer fuer MSHTML in SoftGems ist in einer Demo). Interessanterweise ist das auch gerade die EXE, die nie was mit dem IE oder seinen Controls zu tun hatte. Bei einer anderen EXE des gleichen Softwareprojektes wuerde ich es als Ueberbleibsel abtun.

Olli 18. Apr 2008 22:54

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Hatte gerade eine schlimme Idee :mrgreen:

... was, wenn man mit DEF-Dateien diese Exporte verstecken kann? Hat das schonmal jemand probiert? Ich glaube, ich werde es mal kurz probieren.

DMW 18. Apr 2008 23:11

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Zitat:

Zitat von Olli
Derjenige welcher den Bug gemeldet hat, wurde ja ziemlich abgebuegelt. Scheint, als haette der Entwickler von Borland noch nie was von Crackern gehoert. Die freuen sich ueber jeden Export mit Namen. Das ist defacto ein gutes Argument gegen BCB, immerhin hat Delphi nicht das Problem. Auch habe ich den Verdacht, dass allein durch die Exporte das Smartlinking beeintraechtigt wird, da logischerweise ein Export nicht wegoptimiert werden kann. Aber das ist nur ein Verdacht.

Was das Smart-Linking angeht: ich weiß es auch nicht, aber in c0nt.asm stand irgendetwas davon, daß __CPPDebugHook referenziert werden müsse, damit es der Linker nicht wegoptimiere. Generell scheint sich das also nicht auszuschließen.


Inwiefern die Namen von Units für Cracker von Interesse sind, vermag ich nicht abzuschätzen. Generell ist das zwar eine unnötige Schwachstelle, aber in Packages, in .NET-Assemblies oder in DLLs, die C- oder C++-Interfaces exportieren, ist das ja praktisch unvermeidlich. Als größeres Problem scheint mir, daß dadurch, wie hier beschrieben, die EXE-Datei unnötig vergrößert wird.

In jedem Fall unterschätzt David Dean das Problem offenbar, was sicherlich auch daran liegt, daß der QC-Report für ein neues Feature plädiert, anstatt einfach das Fehlverhalten zu beschreiben.


Gib Bescheid, wenn sich mit einer DEF-Datei etwas machen läßt. Aber es würde mich wundern.

Olli 18. Apr 2008 23:23

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Bin noch am Testen, aber Borland scheint eine andere Syntax fuer DEF-Dateien zu haben.

Wenn 6000 Exporte fuer rund 600 kiB verantwortlich sind, habe ich ca. 154kiB Overhead ;) ... wenn man dann noch annimmt (worin ich durch deinen Kommentar, "daß __CPPDebugHook referenziert werden müsse", bestaerkt wurde) dass diese Methode das Smartlinking behindert, erklaert das auch einiges. Erfahrungsgemaess wuerde ich unser Projekt naemlich durchaus bei ungefaehr 1 MiB einordnen, nicht jedoch bei 2,16 MiB - die Erfahrungen beruhen allerdings auf Delphi, nicht BCB6.

Olli 19. Apr 2008 00:09

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Tja, zu meinem Leidwesen funktioniert das mit der DEF-Datei ueberhaupt nicht. Borland scheint entweder das Schluesselwort NONAME nicht zu kennen, es zu ignorieren, oder die DEF-Datei kommt an einer Stelle ins Spiel, wo sie nichts bewirkt. In jedem Fall ist das Problem damit nach wie vor ungeloest. Insbesondere in Hinblick auf die benutzten Pascal-Units, bei denen ich schlecht die Initialisierung wegnehmen kann.

Das beschriebene Tool (Link aus dem vorletzten Beitrag) habe ich bereits vorher getestet gehabt, obwohl ich nicht wusste, dass es (ja scheinbar) spezifisch auf BCB zugeschnitten ist. Alles in allem suboptimal ... aber Sorgen bin ich mit dem BCB ja gewohnt. Bspw. kann man mit eingeschaltetem DEP (Default bei W2K3) nicht auf die Projektoptionen zugreifen!

Das besagte Tool stellt zumindest in Aussicht, die Exporte wegzuoptimieren, aber bei mir ging danach mit der "korrigierten" EXE erst recht nichts mehr.

jbg 19. Apr 2008 00:11

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Ich werfe einfach mal meinen LibExportRemover in den Raum. Dieser entfernt aus den (statischen) *.lib Dateien der Packages die "__export" Referenzen, die ja wegen dem statischen Linken nicht benötigt werden.
Für die eigenen Dateien bietet das Tool keine Hilfe, da diese nicht als *.lib Datei eingelinkt werden. Aber die Anzahl der Exports dürfte damit schon drastisch zurückgehen.

Olli 19. Apr 2008 00:20

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Hi Andreas, danke fuer deine Muehe. Auch deine DDevExtensions erleichtern "das Leben mit dem Biest" doch gehoerig.

Leider bekomme ich sofort eine Exception bei der ersten LIB-Datei. Hier der Stack-Backtrace:

ChildEBP RetAddr Args to Child
0012f79c 7c827cfb 77e76792 00000002 0012f930 ntdll!KiFastSystemCallRet
0012f7a0 77e76792 00000002 0012f930 00000001 ntdll!NtWaitForMultipleObjects+0xc
0012fac0 00404380 0012fad0 7c828752 0012fe84 kernel32!UnhandledExceptionFilter+0x7c0
WARNING: Stack unwind information not available. Following frames may be wrong.
0012faec 7c828723 0012fe84 0012ffb4 0012fba4 LibExportRemover+0x4380
0012fb94 7c82863c 0012c000 0012fba4 00010007 ntdll!ExecuteHandler+0x24
0012fe74 77e4bee7 0012fe84 00c2a858 0eedfade ntdll!RtlRaiseException+0x3d
0012fed4 0041093b 0eedfade 00000001 00000007 kernel32!RaiseException+0x53
0012ff44 004107f9 00000000 00000012 0012ff90 LibExportRemover+0x1093b
0012ff6c 00410d86 00000012 00000080 00404e52 LibExportRemover+0x107f9
0012ff84 004113c3 00413214 0012ff9c 0041146b LibExportRemover+0x10d86
0012ffc0 77e6f23b 00000000 00000000 7ffdc000 LibExportRemover+0x113c3
0012fff0 00000000 0041128c 00000000 78746341 kernel32!BaseProcessStart+0x23

Danke nochmal,

jbg 19. Apr 2008 00:26

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Zitat:

Zitat von Olli
Leider bekomme ich sofort eine Exception bei der ersten LIB-Datei. Hier der Stack-Backtrace:

Die OMF Lesefunktion des Tools ist ziemlich einfach gestrickt. Soll ja nur aus $A0 "Export Symbol (Borland)" ein $FF "Comment" machen.
Wahrscheinlich kommt da einfach nur ein OMF-Block, den ich nicht bedacht habe.

Auf welche LIB Datei hast du das Tool angewandt? Wenn ich das bei mir (morgen) testen kann, könnte ich das Tool anpassen. Alternativ kann ich dir den (Delphi) Quellcode des Tools auch zukommen lassen.

Olli 19. Apr 2008 00:32

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Hi,

angewandt habe ich es auf eine LIB von Komponenten, die wir hier selber (bzw. die Vorgaenger) gestrickt haben: "FPComponents.lib".

Der Code wuerde mich natuerlich unabhaengig davon interessieren. Wenn du ihn mir noch heute Nacht zuschickst (hier ist es erst 23:30) habe ich noch was zu tun. Und Delphi habe ich ohnehin nur zuhause :mrgreen: ... wuerde dann die Korrektur zurueckschicken, so ich denn eine hingebogen bekommen. Adresse bspw. oliver@assarbad.net

Uebrigens, habe es gerade nochmal explizit mit einer anderen LIB-Datei probiert (diesmal VirtualTreesC6.lib) und bekomme prinzipiell den gleichen Stacktrace. Hast du es jemals mit BCB6 probiert?

Code:
ChildEBP RetAddr Args to Child            
0012f79c 7c827cfb 77e76792 00000002 0012f930 ntdll!KiFastSystemCallRet
0012f7a0 77e76792 00000002 0012f930 00000001 ntdll!NtWaitForMultipleObjects+0xc
*** WARNING: Unable to verify checksum for C:\Program Files\Borland\CBuilder6\Bin\LibExportRemover.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Program Files\Borland\CBuilder6\Bin\LibExportRemover.exe
0012fac0 00404380 0012fad0 7c828752 0012fe84 kernel32!UnhandledExceptionFilter+0x7c0
WARNING: Stack unwind information not available. Following frames may be wrong.
0012faec 7c828723 0012fe84 0012ffb4 0012fba4 LibExportRemover+0x4380
0012fb94 7c82863c 0012c000 0012fba4 00010007 ntdll!ExecuteHandler+0x24
0012fe74 77e4bee7 0012fe84 00c2a858 0eedfade ntdll!RtlRaiseException+0x3d
0012fed4 0041093b 0eedfade 00000001 00000007 kernel32!RaiseException+0x53
0012ff44 004107f9 00000000 00000012 0012ff90 LibExportRemover+0x1093b
0012ff6c 00410d86 00000012 00000080 00404e52 LibExportRemover+0x107f9
0012ff84 004113c3 00413214 0012ff9c 0041146b LibExportRemover+0x10d86
0012ffc0 77e6f23b 00000000 00000000 7ffd8000 LibExportRemover+0x113c3
Code:
0041092c a1c4f84000      mov    eax,dword ptr [LibExportRemover+0xf8c4 (0040f8c4)]
00410931 e8c69fffff     call   LibExportRemover+0xa8fc (0040a8fc)
00410936 e8d538ffff     call   LibExportRemover+0x4210 (00404210)
0041093b 8d4308          lea    eax,[ebx+8] [color=red]<--[/color]
0041093e 8bd6            mov    edx,esi
EBX ist in meinem Fall 0x12f7bc, was meiner Erfahrung nach eine Heapadresse sein muesste. Ich mache mal ne kleine Debugsession ohne Delphi. (Notgedrungen, bin hier noch im Buero und ohne Delphi ;))

Nachtrag 2: Das Problem scheint innerhalb einer Stream-Klasse zu liegen. Die Exception ist also womoeglich einfach nur durchgepfiffen und da nach dem Aufruf an 00410936 EIP auf 0041093b steht, wird das als Adresse der Exception angegeben. Man muesste wohl im Code nachschauen ob da irgendwo bspw. ein ungueltiges Dateioffset angefordert wird und deshalb eine Exception ausgeloest wird.

Nachtrag 3: Die Funktion LibExportRemover+0x4210 wird offenbar nach LibExportRemover+0xa8fc aufgerufen um zu ueberpruefen, "ob was anliegt". Jedenfalls hat diese Funktion (LibExportRemover+0x4210) eine ziemlich simple Logik, die nur danach entscheidet, ob in EAX Null oder ein anderer Wert steht.

Code:
.text:00404210 sub_404210 proc near                   ; CODE XREF: sub_406F88+19p
.text:00404210                                         ; sub_40AA3C+49j ...
.text:00404210 or     eax, eax
.text:00404212 jnz    short loc_40421E
.text:00404214 mov    eax, 216
.text:00404219 call   sub_4047A4
.text:0040421E ; ---------------------------------------------------------------------------
.text:0040421E
.text:0040421E loc_40421E:                            ; CODE XREF: sub_404210+2j
.text:0040421E pop    edx
.text:0040421F push   esp
.text:00404220 push   ebp
.text:00404221 push   edi
.text:00404222 push   esi
.text:00404223 push   ebx
.text:00404224 push   eax
.text:00404225 push   edx
.text:00404226 push   esp
.text:00404227 push   7
.text:00404229 push   1
.text:0040422B push   0EEDFADEh
.text:00404230 push   edx
.text:00404231 jmp    ds:dword_413014
.text:00404231 sub_404210 endp
... nach einem GREP durch die VCL stellt sich das als die Implementierung von _RaiseExcept heraus:

Delphi-Quellcode:
  { ->   EAX    Pointer to exception object    }
  {       [ESP]  Error address          }
Um es kurz zu machen, ich denke, dass der Fehler eine Delphi-Exception vom Typ EListError ist.

Nachtrag 4: Hat irgendwas mit der Verwendung einer THandleStream-Instanz zu tun.

jbg 19. Apr 2008 11:01

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Zitat:

Zitat von Olli
Hast du es jemals mit BCB6 probiert?

Klar. Denn nur für BCB 6 habe ich es geschrieben. Ab C++Builder 2006 werden keine EXPDEF Symbole mehr in die Package-.lib Datei geschrieben.

Was mir ist aber gerade aufgefallen, dass LibExportRemover keine Pfade in den Parametern verträgt. Es kommt sonst zu einem "File not found" Fehler, der wegen des fehlenden Exception Handlings direkt durchgereicht wird.
Man muss also LibExportRemover in dem Verzeichnis aufrufen, in dem die .lib Datei liegt.

Olli 19. Apr 2008 21:18

Re: [BCB] Die nervigen Exporte in erzeugten Programmen
 
Das scheint dann auch der Grund zu sein. Ich schaue mir später an, wie ich das noch gelöst bekomme und schicke es dir dann wieder zu. Danke erstmal für deine Mühen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:31 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