AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Delphi-System-Funktion ersetzen

Ein Thema von himitsu · begonnen am 1. Mär 2012 · letzter Beitrag vom 3. Mär 2012
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#1

Delphi-System-Funktion ersetzen

  Alt 1. Mär 2012, 14:21
Delphi-Version: XE
Wie kann ich eine Funktion aus der unit System überschreiben/ersetzen?

Ich hab hier ein Problem "Interface nicht unterstützt", welches ich einfach nicht gelöst bekomme.
Im Programm läuft es, aber in der IDE bekomme ich einige Formulare einfach nicht mehr geöffnet. (PAS wird geladen, aber nicht die DFM)
Da ist einfach kein Arbeiten möglich, wenn man die IDE nicht nutzen kann. (statt einen Bug 15-30 Minuten lang mit Hilfe des Formdesigners zu suchen, hab ich mich über 1,5 Stunden durch die DFM als Text gequält)

Ich vermute, daß es irgendwo ein Problem in unseren Komponenten/Packages ist,
aber egal wie ich die IDE debugge, ich finde die Fehlerstelle nicht und wenn, dann schafft es Delphi einfach nicht den Stacktrace (ordentlich) anzuzeigen, so daß ich die eigentliche fehlerauslösende Stelle finden könnte.

Nun hab ich eine Funktion, welche die Fehlermeldung etwas verständlicher macht.
Und diese müßte jetzt "blos" noch mit System._InftCast (so heißt es in der system.pas) oder vielleicht auch sowas wie System.IntfCast ersetzen.

Also quasi ein
Delphi-Quellcode:
MOV EAX, @ExtendedIntfCast
JMP EAX
bei dieser Funktion einfügen/drüberschreiben.

Aber ich kann die Adresse diese Prozedur, bzw. ihren öffentlich Namen, einfach nicht finden.
In der System.pas steht die _IntfCast zwar im Interface-Bereich, aber das hat ja (bei dieser Unit) nix zu sagen.

Delphi-Quellcode:
uses
  SysConst, SysUtils, Classes, Controls, Forms, RTTI;

procedure ExtendedIntfCast(var Dest: IInterface; const Source: IInterface; const IID: TGUID);
// PIC: EBX must be correct before calling QueryInterface
function ReturnAddr: Pointer;
  asm
    MOV EAX, [EBP+4]
  end;
function Compare(const G1, G2: TGUID): Boolean;
  begin
    Result := CompareMem(@G1, @G2, SizeOf(TGUID));
  end;
const
  ObjCastGUID: TGUID = '{CEDF24DE-80A4-447D-8C75-EB871DC121FD}';
var
  Intf: IInterface;
  Obj: TObject;
  S: string;
  RTyp: TRttiType;
begin
  if Source <> nil then begin
    if Source.QueryInterface(IID, Intf) <> 0 then begin
      // Fehlermeldung und GUID des angeforderten Interfaces
      S := SIntfCastError + sLineBreak + GUIDToString(IID);
      // Interface-Bezeichnung suchen
      for RTyp in TRttiContext.Create.GetTypes do
        if (RTyp is TRttiInterfaceType) and Compare(TRttiInterfaceType(RTyp).GUID, IID) then
          S := S + ' = ' + TRttiInterfaceType(RTyp).DeclaringUnitName + '.' + TRttiInterfaceType(RTyp).Name;
      // weitere Infos, wenn sich intern ein Delphi-Objekt versteckt
      if Source.QueryInterface(ObjCastGUID, Obj) <> 0 then begin
        // Bezeichnung der Klasse
        S := S + ' < ' + Obj.UnitName + '.' + Obj.ClassName;
        if Obj is TComponent then begin
          // Komponenten-Name
          if TComponent(Obj).Name <> 'then
            S := S + '-' + TComponent(Obj).Name;
          // worauf sich diese Komponente befindet
          if Obj is TWinControl then
            while Assigned(TWinControl(Obj).Parent) do begin
              Obj := TWinControl(Obj).Parent;
              if (Obj is TForm) or (Obj is TFrame) then begin
                S := S + '@' + Obj.UnitName + '.' + Obj.ClassName;
                if TComponent(Obj).Name <> 'then
                  S := S + '-' + TComponent(Obj).Name;
              end;
            end;
        end;
      end;
      raise EIntfCastError.Create(S) at ReturnAddr;
    end else
      Dest := Intf;
  end else
    Dest := nil;
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 1. Mär 2012 um 14:23 Uhr)
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

AW: Delphi-System-Funktion ersetzen

  Alt 1. Mär 2012, 14:52
http://www.delphipraxis.net/21619-um...saufrufen.html
Handle with care
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#3

AW: Delphi-System-Funktion ersetzen

  Alt 1. Mär 2012, 15:11
Ist gut und schön und im Prinzip funktioniert es,

wenn man den Zeiger zur Funktion kennt/bekommt.
Und das ist mein Hauptproblem ... an den komm ich nicht ran.

Delphi-Quellcode:
begin
  p := @_IntfCast;
  p := @IntfCast;
  p := @System._IntfCast;
  p := @System.IntfCast;
end;

asm
  call _IntfCast;
  call IntfCast;
  call System._IntfCast;
  call System.IntfCast;
end;
Es heißt immer _IntfCast oder IntfCast sei unbekannt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#4

AW: Delphi-System-Funktion ersetzen

  Alt 1. Mär 2012, 15:41
Also bei meinem Delphi 5 kommt vor den Funktionen IntfClear() und IntfCast() die Funktion LoadResString();
Man könnte nun den Zeiger auf LoadResString() anfordern und einen festen Offset dazuaddieren.
Um an den Offset zu kommen muss man sich die Adressen der Funktionen im CPU-Fenster anzeigen lassen und voneinander abziehen.
Das ist natürlich sehr unsauber aber der Zweck heiligt die Mittel.

Delphi-Quellcode:
// Codebeispiel um die Funktion IntfCast zu finden
procedure TForm1.ButtonTestClick(Sender: TObject);
var
   i : IDispatch;
   t : IUnknown;
begin
   // Breakpoint
   asm
      int 3
   end;
   // CPU-Fenster anzeigen lassen und per Singlestep weiter bis @IntfCast gehen
   i := t as IDispatch;
end;
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von guinnes
guinnes

Registriert seit: 28. Feb 2007
Ort: Bottrop
265 Beiträge
 
Delphi 5 Enterprise
 
#5

AW: Delphi-System-Funktion ersetzen

  Alt 1. Mär 2012, 15:42
Das wird wohl an der Compiler-Magic liegen.

In einem Contruct wie BlaBla := Fu as Bar sollte die Funktion aufgerufen werden ( Kann man ja im integrierten Disassembler überprüfen )

Mist, zu langsam
Glückauf
  Mit Zitat antworten Zitat
Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#6

AW: Delphi-System-Funktion ersetzen

  Alt 1. Mär 2012, 15:48
Delphi-Quellcode:
function GetIntfCastAddr: Pointer;
asm
  lea eax,System.@IntfCast;
end;
Thomas Nitzschke
Google Maps mit Delphi
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#7

AW: Delphi-System-Funktion ersetzen

  Alt 1. Mär 2012, 17:07
Delphi-Quellcode:
function GetIntfCastAddr: Pointer;
asm
  lea eax,System.@IntfCast;
end;
Hatte zwar schon einige Varianten durchprobiert.
Ich würde dich abknutschen, aber ich glaub ich laß das.

Delphi-Quellcode:
var
  PIntfCast: Pointer;

begin
  RedirectProcedureCall(Pointer($004099E8), @ExtendedIntfCast);

  RedirectProcedureCall(Pointer(NativeInt(@TInterfacedObject.AfterConstruction) - 60), @ExtendedIntfCast);

  asm
    LEA EAX, System.@IntfCast
    MOV &PIntfCast, EAX
  end;
  RedirectProcedureCall(PIntfCast, @ExtendedIntfCast);
Da ich diese Funktion auch demnächte veröffentlichen würde (in 'ner Unit verpackt), gefällt mir Letzeres natürlich besser.
(muß dann nur noch irgendwann mal sehn, wie das mit Win64 und Co. aussieht)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#8

AW: Delphi-System-Funktion ersetzen

  Alt 1. Mär 2012, 17:11
@himitsu
das sieht irgendwie abenteuerlich um nicht zu sagen bedrohlich aus
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#9

AW: Delphi-System-Funktion ersetzen

  Alt 1. Mär 2012, 17:34
Was davon?
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#10

AW: Delphi-System-Funktion ersetzen

  Alt 1. Mär 2012, 17:36
alles, aber das dürfte daran liegen dass ich Dir nicht mehr folgen kann
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz