AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Zugriff auf ein TImage einer externen Anwendung
Thema durchsuchen
Ansicht
Themen-Optionen

Zugriff auf ein TImage einer externen Anwendung

Ein Thema von KoS · begonnen am 15. Feb 2007 · letzter Beitrag vom 21. Mär 2007
Antwort Antwort
Seite 2 von 12     12 34     Letzte »    
KoS

Registriert seit: 9. Jun 2006
55 Beiträge
 
#11

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 19. Feb 2007, 17:30
Hallo,
Zitat von sirius:
Ich hab jetzt keine weiteren Kommentare, da ich nur ein wenig rumgespielt habe. Letztenendes macht es nix andere, als:
Also ich hab das mal eben ausprobiert und bekomme Folgendes Resultat:
Delphi-Quellcode:
TApplication
THintWindow
TForm1
Was mir jetzt mal sagt das eigentlich nur die "Hauptklassen" angezeigt nicht jedoch die Komponenten auf dem Form.

Wenn ich jedoch direkt folgendes mache:
Delphi-Quellcode:
for i:=0 to Form1.componentcount-1 do begin
  memo1.lines.add(Form1.component[i].classname);
  //Und wenn classname TImage ist, dann noch die Abmaße aufschreiben
end;
Erhalte ich nur die Komponenten von dem Fenster:
Delphi-Quellcode:
TImage
TImage
TMemo
TButton
Hab ich irgendwas vergessen oder warum funktioniert das nicht so wie es soll?
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#12

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 19. Feb 2007, 19:47
Hmm, rätselhaft. vorhin ging es so bei mir jetzt hatte ich dasselbe Ergebnis und muss die eine Zeile ändern:
p:=pointer(getwindowlong(myhandle,gwl_wndproc)+9); Aus der 35 ist eine 9 geworden. das ist halt meine Referenz. Ich hab leider den Code von heut mittag verworfen. Da kann ich leider nicht überprüfen warum das vorhin eine 35 war. Der Schlüssel liegt in der Funktion MakeObjectInstance der Unit Classes, aber da hab ich jetzt grad keine Lust mich weiter reinzuarbeiten. Vielleicht klappt die 9 ja ab jetzt .

Man könnte natürlich auch Tform1 nehmen und dann weiter suchen. aber das ist nicht gerade sinnvoll.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
KoS

Registriert seit: 9. Jun 2006
55 Beiträge
 
#13

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 19. Feb 2007, 21:17
Ahhhja ... mit der 9 sieht das ganze doch gleich viel besser aus! Vielen Dank!

Jetzt hab ich aber doch noch 2 Fragen, zum einen - wird es doch auch bestimmt möglich sein den Namen es TImages neben dem Handle ausfindig zu machen? Damit ich dann besser die TImages unterscheiden kann und wie du beim "s='TImage'" eine if-Abfrage machen kann.

Zum anderen, wenn ich den ganzen Code mit myhandle:=getforegroundwindow; mache, bekomm ich eine Zugriffsverletzung, sobald ein anderes Programm im Vordergrund ist, also eben jenes was ich "auslesen" möchte.
Realisiert mit einem Timer der alle 5 Sec. die Button Prozedur ausführt. Funktioniert aber auf dem eigenen Form.
Dazu noch eine Idee?

Die ganze WinAPI geschichte was du hier bisher aufgebracht hast ist für mich noch ein buch mit 7 Siegeln.
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#14

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 19. Feb 2007, 22:10
Ich hab diesen code, von dem größtenteils Bahnhof verstehe , mal etwas umgeschrieben, sodass er den namen der komponente anzeigt. Allerdings funktioniert das nur bei formularen in der eigenen anwendung, bei formularen aus anderen delphi anwendungen streikt er, und zwar bei   p:=p^; Ich habe mal gehört, dass die VCL von zwei Anwendungen nicht miteinander kompatibel ist. Liegt das daran?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var pi,p,pm:ppointer;
    s:string;
    c:pchar;
    i,a:integer;
    obj: tPersistent;
    myhandle: hwnd;
begin
  memo1.clear;
  myhandle:=...; //myhandle ist das einzige, was ich benötige

  p:=pointer(getwindowlong(myhandle,gwl_wndproc)+9);


  pm:=p;
  p:=p^;
  p:=pointer(integer(p^)-44);
  p:=p^;
  c:=pchar(p);
  s:='';
  inc(c);
  for i:=1 to pbyte(p)^ do begin
    s:=s+c^;
    inc(c);
  end;
  memo1.lines.Add(s); //classname des Windows

  pm:=pointer(integer(pm^)+16);

  for a:=0 to pinteger(integer(pm^)+8)^-1 do begin //von 0 bis componentcount

    p:=pointer(integer(pm^)+4);
    p:=pointer(integer(p^)+4*a);
    pi:=p; //pi^ ist Zeiger auf ein Objekt

    obj := TPersistent(pi^);
    memo1.lines.add(obj.GetNamePath);
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#15

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 07:41
@namenlozer
In dem Fall kannst du noch viel früher ansetzen. Bei der Adresse der WndProc-funktion (+9 Bytes dahinter) steht die Adresse eines TWinControls. Nämlich genau das, welches die Messages bekommt.
Demnach könnte man ab hier mit VCL-Komponenten arbeiten:
Delphi-Quellcode:
p:=pointer(getwindowlong(myhandle,gwl_wndproc)+9);
obj:=Twincontrol(p^);
memo1.Lines.add(obj.Name);
//.. und dann weiter über obj.componentcount bzw. obj.component[0..obj.componentcount]
Aber das war nicht sinn der Sache. Ich wollte ja komplett ohne VCL und nur mit Adressen/Pointern auskommen, weil (und jetzt kommt der Knackpunkt) man damit (hoffentlich ) auch in fremden Prozessen recht einfach lesen kann. Ihr habt ja beide schon bemerkt, dass der Code nur im eigenen Programm/Prozess funktioniert. Das ist auch gut so. Denn schließlich ist die CPU im Protected Mode und Windows ein sicheres Betriebsystem , wo man nicht einfach in fremden Adressbereichen lesen und schreiben kann/darf. Das wäre ja zu schön, da könnte ja jeder Trojaner einfach so eueren Programmspeicher (inkl. Passwörter) auslesen.
Ok, soviel Witz am Rande, kommen wir zurück zur Realität (ihr wisst anscheinend noch nicht, was virtueller Adressraum bedeutet -->unbedingt mal bei Wiki oder so reinlesen). Und die Realität kennt Windows und Windows kenn:
-openprocess
-readprocessmemory
-writeprocessmemory
So, und damit können wir in einem fremden Prozess auch mitlesen,... irgendwie. Ich schau mal.


Ansonsten, was ich da oben bisher gemacht habe, sieht nur kompliziert aus, ist aber nur ein wenig Adressrechnung. Ich springe immer von einer Adresse zur nächsten und rechne zwischendruch konstante Werte dazu (entsprechend wie die VCL aufgebaut ist). Als Startadresse nehme ich mir die WndProc-Funktion, die ich ja recht einfach aus dem Window-Handle bekomme (getwindowlong).
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#16

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 09:42
Ok, bei mir getestet und es funktioniert:
Delphi-Quellcode:
unit U_getImage;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;


const mymsg=WM_User+1;

type TSearchtype=(sClassName,sName);
type PMemory=^TMemory;
     TMemory=packed record
       Thread:array[0..1023] of char;
       Postmessage:function(wnd:hwnd;msg,wparam,lparam:cardinal):bool;stdcall;
       exitthread:procedure(exitcode:integer);stdcall;
       getwindowlong:function(wnd:hwnd;index:integer):cardinal;stdcall;
       watchwnd:hwnd;
       backwnd:hwnd;
       backmsg:integer;
       count:integer;
       SearchType:TSearchtype;
       vgl:array[0..31] of char; //kann noch verlängert werden
       vgllength:integer;
     end;



type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure GetMyMsg(var msg:TMessage);message mymsg;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


function injectThread(memory:Pmemory):integer; stdcall;
{Diese Funktion landet nachher in einem fremden Process.
Deswegen dürfen hier keine Funktionen von Delphi benutzt werden
(inkl. Stringoperationen, VCL, etc.).}

var pi,p,pm:ppointer;
    i,a:integer;
    c:pchar;
    left,top,width,height:smallint;
    same:boolean;
    wparam,lparam:cardinal;
begin
  lefT:=0;
  top:=0;
  width:=0;
  height:=0;
  p:=pointer(memory^.getwindowlong(memory^.watchwnd,gwl_wndproc)+9);


  //Ab hier wie gehabt, nur die Stringoperationen verändert
  //und die Variante sName eingefügt

  pm:=pointer(integer(p^)+16);

  for a:=0 to pinteger(integer(pm^)+8)^-1 do begin //von 0 bis componentcount

    p:=pointer(integer(pm^)+4);
    p:=pointer(integer(p^)+4*a);
    pi:=p; //pi^ ist Zeiger auf ein Objekt


    if memory^.SearchType=sClassname then begin
      p:=p^;
      p:=pointer(integer(p^)-44);
    end else
      p:=pointer(integer(p^)+8);

    p:=p^;

    c:=pchar(p);
    if (pbyte(p)^=memory^.vgllength)or(memory^.SearchType=sName) then begin
      if memory^.SearchType=sClassName then inc(c);
      same:=false;
      for i:=1 to memory^.vgllength do begin
        if memory^.vgl[i-1]<>c^ then break;
        same:=i=memory^.vgllength;
        inc(c);
      end;
      if same then begin
        dec(memory^.count);
        if (memory^.count=0)or(memory^.SearchType=sName) then begin
          left:=(pinteger(integer(pi^)+$40)^);
          top:=(pinteger(integer(pi^)+$44)^);
          width:=pinteger(integer(pi^)+$48)^;
          height:=pinteger(integer(pi^)+$4C)^;
          break;
        end;
      end;
    end;

  end;

  //4 Zahlen in 2*32Bit kopieren
  wparam:=left*65536+top;
  lparam:=width*65536+height;
  //Ergebnis Nach Hause senden
  memory^.Postmessage(memory^.backwnd,memory^.backmsg,wparam,lparam);
  result:=0;
  //Thread beenden
  memory^.exitthread(0);
end;
procedure endpoint;
//ohne Funktion nur zum finden des Address-endes von injcetThread
asm
nop
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;

procedure TForm1.Button1Click(Sender: TObject);
var myhandle:hwnd;
    mem:TMemory;
    lib:THandle;
    size:integer;
    process:cardinal;
    processid:cardinal;
    procmem:PMemory;
    tmp:cardinal;
    threadID:cardinal;
    thread:THandle;
begin
  memo1.clear;
  myhandle:=findwindow(nil,'PImage'); //Beispielprogramm finden

  //mem ist der Record der nachher in den anderen Process kopiert wird
  mem.backwnd:=self.Handle; //Handle, damit wir Nachrichten zurückschicken können
  mem.backmsg:=mymsg; //Message-Nr., damit wir unsere Message wiederfinden
  mem.watchwnd:=myhandle; //Das Handle für getwindowlong
  //mem.count:=1; //welches TImage (=mem.vgl)? (nur für Searchtype=sClassName)
  mem.vgl:='Image3'; //der Vergleichsstring
  mem.vgllength:=6; //Länge des Vergleichsstrings
  mem.SearchType:=sName; //vgl vergleichen mit Classname oder Name
  //kopieren der funktion injectthread in den Record
  size:=integer(@endpoint)-integer(@injectThread);
  move(injectthread,mem.thread,size);
  //EinsprungAdresse von 3 WinAPI-funktionen, die nacher benötigt werden
  //Die Adressen sind in jedem Process gleich
  lib:=getmodulehandle('user32.dll');
  mem.Postmessage:=getprocaddress(lib,'PostMessageA');
  mem.getwindowlong:=getprocaddress(lib,'GetWindowLongA');
  lib:=getmodulehandle('kernel32.dll');
  mem.exitthread:=getprocaddress(lib,'ExitThread');

  //Thread-Record in anderen Process kopieren und mem.Thread starten
  getwindowthreadprocessid(myhandle,@processid);
  process:=openprocess(PROCESS_ALL_ACCESS,false,processid);
  //Speicher reservieren
  procmem:=virtualallocex(process,nil,sizeof(Tmemory),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  //Kopieren
  writeprocessmemory(process,procmem,@mem,sizeof(TMemory),tmp);
  //Starten
  thread:=createremotethread(process,nil,0,@procmem.thread,procmem,0,threadid);
  //Warten bis injectthread beendet ist
  waitforsingleobject(thread,infinite);
  //Speicher wieder freigeben
  closehandle(thread);
  virtualfreeex(process,procmem,0,mem_decommit);
  closehandle(process);

end;
procedure TForm1.GetMyMsg(var msg:TMessage);
begin
  memo1.Lines.add(inttostr(msg.WParamlo));
  memo1.Lines.add(inttostr(msg.WParamhi));
  memo1.Lines.add(inttostr(msg.lParamlo));
  memo1.Lines.add(inttostr(msg.lParamhi));
end;
end.
Man kann auch nach ClassName suchen (dann ist mem.count notwendig, da es ja mehrere TImages geben kann):
Delphi-Quellcode:
  mem.count:=2; //welches TImage (=mem.vgl)? (nur für Searchtype=sClassName)
  mem.vgl:='TImage'; //der Vergleichsstring
  mem.vgllength:=6; //Länge des Vergleichsstrings
All das funktioniert wie gesagt nur mit Programmen, die mit der VCL programmiert wurden, genauer gesagt, mit der VCL die in Delphi 7 ist (Ich weis ja nicht ob sich an diesen grundlegenden Strukturen bis D2006 etwas geändert hat).


Und nun noch zum Beispielprogramm:
Er sucht jetzt quasi ein Window, dessen Titel PImage ist, das sieht so aus (zweites Programm):
Delphi-Quellcode:
unit U_Image;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  self.caption:='PImage';
end;

end.

PS: Eigentlich sollte man noch Sicherheiten einbauen. An der Stelle wo der Thread-Record in den anderen Process kopiert und gestartet wird, kann man an den Ergebnissen der funktionen sehen, ob es überhaupt geklappt hat. Aber das überlasse ich dem geneigten Leser .

Edit: "break" eingefügt. Man muss ja nicht weiter suchen, wenn man schon gefunden hat.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
KoS

Registriert seit: 9. Jun 2006
55 Beiträge
 
#17

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 12:43
Das finden der TImages nach Namen funktioniert soweit richtig super!
Auch das Zeichnen eines Textes mit Canvas in das Form klappt ganz gut.

Es gibt aber nach wie vor noch ein anliegen was ich durchs rum probieren noch nicht so richtig hinbekommen habe.
Ich habs mit folgendem Versucht:
Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
var dc:hdc; //Device Context Handle
    Canvas:Tcanvas;
begin
  dc:=getwindowdc(myhandle);
  //TCanvas auf den Device Context setzen
  canvas:=TCanvas.Create;
  canvas.Handle := dc;
  Image1.Picture.LoadFromFile('mein_bild.jpg');
  Image1.Picture.Graphic.SetSize(ImgWidth,ImgHeight);
  canvas.Draw(ImgLeft,ImgTop,Image1.Picture.Graphic);
  canvas.Free;
  releasedc(myhandle,dc);
end;
Bei dem Nutzen des SetSize erhalte ich folgenden Fehler: "Cannot change the size of a JPEG image".
Wenn ich das SetSize vom Image1 raus lasse zeichnet er mir zwar das Bild auf das Ziel-Form, aber in voller Größe.
Ich möchte es aber nur entweder in der Größe des eigenen Image1 oder aus den ImgWidth,ImgHeigth Variablen welche dem des ziel TImage entsprechen.


Zudem noch eine Frage, wie bekomm ich jetzt noch den Caption-Wert wenn es sich nicht um ein TImage sonder um ein TLable handelt?

Vielen Dank!
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#18

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 13:06
Also bei D7 gibt es kein TGraphic.SetSize. Das muss irgendwie neu sein. Da kann ich dir auch nicht weiterhelfen (außer wenn ich zu Hause mal mei TurboDelphi anschmeiße, aber da hab ich wahrscheinlich keine Zeit). Wahrscheinlich musst du irgendwie das jpg in ein Bitmap umwandeln. Dazu gibts TJPEGImage und die Methode DIBneeded. Musst du mal irgendwie damit probieren.

Zitat:
Zudem noch eine Frage, wie bekomm ich jetzt noch den Caption-Wert wenn es sich nicht um ein TImage sonder um ein TLable handelt?
Du willst aus dem Programm, wo du Images gesucht hast auch den Inhalt von Labels wissen? Erklär mal genauer!
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
KoS

Registriert seit: 9. Jun 2006
55 Beiträge
 
#19

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 14:05
Zitat von sirius:
Also bei D7 gibt es kein TGraphic.SetSize.
Ich habs auch mit TGraphic.Height, TGraphic.Width versucht, kommt ebenfalls der Fehler.
Soweit ich das sehe ist das SetSize nur ne Funktion die die beiden Zeilen in 1 zusammenfasst.

Zitat von sirius:
Zitat:
Zudem noch eine Frage, wie bekomm ich jetzt noch den Caption-Wert wenn es sich nicht um ein TImage sonder um ein TLable handelt?
Du willst aus dem Programm, wo du Images gesucht hast auch den Inhalt von Labels wissen? Erklär mal genauer!
Ja genau so wie du es gesagt hast. In dem Form wo ich die Images suche gibt es auch Labels dessen Text ich wissen möchte. Ebenfalls Namen bekannt.

Edit:
Mit hilfe deines TJPEGImage.DIBNeeded bin ich auf ein Thread gestoßen der folgendes Resultat hat:
Delphi-Quellcode:
var rect : TRect;

rect.Left := ImgLeft;
rect.Top := ImgTop;
rect.Right := ImgLeft + ImgWidth;
rect.Bottom := ImgTop + ImgHeight;
canvas.StretchDraw(rec,Image1.Picture.Graphic);
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#20

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 14:26
Zitat:
Mit hilfe deines TJPEGImage.DIBNeeded bin ich auf ein Thread gestoßen der folgendes Resultat hat:
Wenn es funktioniert... Mit dem Canvas kannst du machen, was du auch sonnst in deiner eigenen Anwendung machen kannst.
Übrigens: das Canvas wird aber genau wie in deiner eignen Anwendung übermalt, wenn z.B. ein anderes Fenster drüber geschoben wird.


Zu dem Label: Ich habe es gefunden. Aber hier bin ich mir am wenigsten sicher, dass der Code generell so eingesetzt werden kann. Bei mir klappts erstmal:
Delphi-Quellcode:
unit U_getImage;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;


const mymsg=WM_User+1;

type TSearchtype=(sClassName,sName,sCaption);
type PMemory=^TMemory;
     TMemory=packed record
       Thread:array[0..1023] of char;
       Postmessage:function(wnd:hwnd;msg,wparam,lparam:cardinal):bool;stdcall;
       exitthread:procedure(exitcode:integer);stdcall;
       getwindowlong:function(wnd:hwnd;index:integer):cardinal;stdcall;
       watchwnd:hwnd;
       backwnd:hwnd;
       backmsg:integer;
       count:integer;
       SearchType:TSearchtype;
       vgl:array[0..31] of char;
       vgllength:integer;
     end;



type
  TForm1 = class(TForm)
    Image1: TImage;
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure GetMyMsg(var msg:TMessage);message mymsg;
    procedure GetMyCaption(var msg:TMessage);message mymsg+1;
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }
    myhandle:hwnd;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


function injectThread(memory:Pmemory):integer; stdcall;
{Diese Funktion landet nachher in einem fremden Process.
Deswegen dürfen hier keine Funktionen von Delphi benutzt werden
(inkl. Stringoperationen, VCL, etc.).}

var pi,p,pm:ppointer;
    i,a:integer;
    c:pchar;
    left,top,width,height:smallint;
    same:boolean;
    wparam,lparam:cardinal;
begin
  wparam:=0;
  lparam:=0;
  p:=pointer(memory^.getwindowlong(memory^.watchwnd,gwl_wndproc)+9);


  pm:=pointer(integer(p^)+16);

  for a:=0 to pinteger(integer(pm^)+8)^-1 do begin //von 0 bis componentcount

    p:=pointer(integer(pm^)+4);
    p:=pointer(integer(p^)+4*a);
    pi:=p; //pi^ ist Zeiger auf ein Objekt

    if memory^.SearchType=sClassname then begin
      p:=p^;
      p:=pointer(integer(p^)-44);
    end else
      p:=pointer(integer(p^)+8);

    p:=p^;

    c:=pchar(p);
    if (pbyte(p)^=memory^.vgllength)or(memory^.SearchType in[sName,sCaption]) then begin
      if memory^.SearchType=sClassName then inc(c);
      same:=false;
      for i:=1 to memory^.vgllength do begin
        if memory^.vgl[i-1]<>c^ then break;
        same:=i=memory^.vgllength;
        inc(c);
      end;
      if same then begin
        dec(memory^.count);
        if (memory^.count=0)or(memory^.SearchType in [sName,sCaption]) then begin
          if memory^.SearchType=sCaption then begin
            p:=pointer(integer(pi^)+$64);
            wparam:=cardinal(p^);
            c:=pchar(p^);
            while c^<>#0 do begin
              inc(c);
              inc(lparam);
            end;
            inc(memory^.backmsg);
          end else begin
            left:=pinteger(integer(pi^)+$40)^;
            top:=pinteger(integer(pi^)+$44)^;
            width:=pinteger(integer(pi^)+$48)^;
            height:=pinteger(integer(pi^)+$4C)^;
            //4 Zahlen in 2*32Bit kopieren
            wparam:=left*65536+top;
            lparam:=width*65536+height;
          end;
          break;
        end;
      end;
    end;

  end;

  //Ergebnis Nach Hause senden
  memory^.Postmessage(memory^.backwnd,memory^.backmsg,wparam,lparam);
  result:=0;
  //Thread beenden
  memory^.exitthread(0);
end;
procedure endpoint;
//ohne Funktion nur zum finden des Address-endes von injcetThread
asm
nop
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;

procedure TForm1.Button1Click(Sender: TObject);
var mem:TMemory;
    lib:THandle;
    size:integer;
    process:cardinal;
    processid:cardinal;
    procmem:PMemory;
    tmp:cardinal;
    threadID:cardinal;
    thread:THandle;
begin
  memo1.clear;
  myhandle:=findwindow(nil,'PImage'); //Beispielprogramm finden
  if myhandle=0 then exit;

  //mem ist der Record der nachher in den anderen Process kopiert wird
  mem.backwnd:=self.Handle; //Handle, damit wir Nachrichten zurückschicken können
  mem.backmsg:=mymsg; //Message-Nr., damit wir unsere Message wiederfinden
  mem.watchwnd:=myhandle; //Das Handle für getwindowlong
  mem.count:=6; //welches TControl (=mem.vgl)? (nur für Searchtype=sClassName)
  mem.vgl:='Label2'; //der Vergleichsstring
  mem.vgllength:=6; //Länge des Vergleichsstrings
  mem.SearchType:=sCaption; //vgl vergleichen mit Classname oder Name oder Caption zurücksenden
  //kopieren der funktion injectthread in den Record
  size:=integer(@endpoint)-integer(@injectThread);
  move(injectthread,mem.thread,size);
  //EinsprungAdresse von 3 WinAPI-funktionen, die nacher benötigt werden
  //Die Adressen sind in jedem Process gleich
  lib:=getmodulehandle('user32.dll');
  mem.Postmessage:=getprocaddress(lib,'PostMessageA');
  mem.getwindowlong:=getprocaddress(lib,'GetWindowLongA');
  lib:=getmodulehandle('kernel32.dll');
  mem.exitthread:=getprocaddress(lib,'ExitThread');

  //Thread-Record in anderen Process kopieren und mem.Thread starten
  getwindowthreadprocessid(myhandle,@processid);
  process:=openprocess(PROCESS_ALL_ACCESS,false,processid);
  //Speicher reservieren
  procmem:=virtualallocex(process,nil,sizeof(Tmemory),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  //Kopieren
  writeprocessmemory(process,procmem,@mem,sizeof(TMemory),tmp);
  //Starten
  thread:=createremotethread(process,nil,0,@procmem.thread,procmem,0,threadid);
  //Warten bis injectthread beendet ist

  waitforsingleobject(thread,infinite);
  //Speicher wieder freigeben
  closehandle(thread);
  virtualfreeex(process,procmem,0,mem_decommit);
  closehandle(process);

end;
procedure TForm1.GetMyMsg(var msg:TMessage);
begin
  memo1.Lines.add(inttostr(msg.WParamlo));
  memo1.Lines.add(inttostr(msg.WParamhi));
  memo1.Lines.add(inttostr(msg.lParamlo));
  memo1.Lines.add(inttostr(msg.lParamhi));
end;
procedure TForm1.GetMyCaption(var msg:TMessage);
var process,processID,tmp:cardinal;
    s:string;
begin
  if myhandle=0 then exit;

  //in msg.wparam steht der Pointer auf das TLabel.caption im anderen Process
  //in msg.lparam die Länge des TCaption

  getwindowthreadprocessid(myhandle,@processid);
  process:=openprocess(PROCESS_VM_READ,false,processid);
  setlength(s,msg.LParam);
  readprocessmemory(process,pointer(msg.wparam),@s[1],msg.lparam,tmp);
  closehandle(process);
  memo1.Lines.add(s);
end;

end.
Ich hab die injectThread angepasst um die Caption zu finden. Und es ist die GetmyCaption dazugekommen um die neue Message zu verarbeiten. In die Erste konnte ich es nicht mehr reinpacken.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 12     12 34     Letzte »    


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 14:07 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