AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Undokumentierter Sendmessage-Befehl
Thema durchsuchen
Ansicht
Themen-Optionen

Undokumentierter Sendmessage-Befehl

Ein Thema von PinkFloydFan · begonnen am 4. Sep 2011 · letzter Beitrag vom 6. Sep 2011
Antwort Antwort
Seite 2 von 4     12 34      
Benutzerbild von PinkFloydFan
PinkFloydFan

Registriert seit: 4. Dez 2007
Ort: Straubing
54 Beiträge
 
Delphi 2010 Architect
 
#11

AW: Undokumentierter Sendmessage-Befehl

  Alt 5. Sep 2011, 08:22
Guten Morgen DeddyH!

Static Labels sind auf keinen Fall.
Mit z.B. Winspy erhalte ich keine Handles. Einzig für ein TPanel,
welches die übergeordnete Komponente dieser 14 Labels darstellt.

Vielleicht gibts über das TPanel nen Ansatz??

Hab mal spasseshalber einen Memory-Dump dieses Programms erzeugt. Die Captions dieser Label sind da schon enthalten, aber immer an anderen Offsets. ( Und auch die vorherigen Captions.. also fast schon wie ne History..)
Irgendwo muss Windows ja mitgeteilt werden, welcher Text wo zu malen ist..

Geändert von PinkFloydFan ( 5. Sep 2011 um 08:37 Uhr)
  Mit Zitat antworten Zitat
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#12

AW: Undokumentierter Sendmessage-Befehl

  Alt 5. Sep 2011, 08:47
Ich habe auch die Vorschläge in http://www.delphipraxis.net/86561-zu...wendung-2.html durchprobiert, was ja an sich auch funktioniert. Nur kenne ich die Namen der Labels nicht. Label1, Label2 usw sinds jedenfalls nicht. Die können ja jeden X-beliebigen Namen haben, zB LblIrgendwas oder ArtikelNrLabel oder sonst was...
An die Namen kommst du z.B. ganz leicht mittels ResHacker ran.
Miniaturansicht angehängter Grafiken
labels.png  
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#13

AW: Undokumentierter Sendmessage-Befehl

  Alt 5. Sep 2011, 08:52
Aber wie kommt man von außen an die Beschriftung? WM_GETTEXT usw. scheiden ja mangels Fensterhandle aus.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von PinkFloydFan
PinkFloydFan

Registriert seit: 4. Dez 2007
Ort: Straubing
54 Beiträge
 
Delphi 2010 Architect
 
#14

AW: Undokumentierter Sendmessage-Befehl

  Alt 5. Sep 2011, 09:02
Moin Morphie!

jo!! Das sieht gut aus!! Werde ich dann gleich versuchen, wenn ich in der Maloche bin..

Melde mich wenn ich ein Ergebnis habe..


@DeddyH:

so kommt man dran: (Source von Sirius, Link weiter oben)

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 <-------------------------------------------------------------------------------------------- HIER
  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.
Natürlich muss dieser Source noch entsprechend aufbereitet werden und einige Sachen entfallen, aber das Prinzip funktioniert..
  Mit Zitat antworten Zitat
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#15

AW: Undokumentierter Sendmessage-Befehl

  Alt 5. Sep 2011, 09:12
das hier sollte wohl auch schon reichen:
Delphi-Quellcode:
function GetLabelText(ParentHandle: HWND; LabelName: string): string;
var
  pi, p, pm: ppointer;
  a: integer;
  obj: tPersistent;
  myhandle: hwnd;
begin
  Result := '';
  myhandle := ParentHandle;
  p := pointer(getwindowlong(myhandle, gwl_wndproc) + 9);
  pm := p;
  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^);
    if obj is TLabel then
    begin
      if (TLabel(obj).Name = LabelName) then
      begin
        Result := TLabel(obj).Caption;
        break;
      end;
    end;
  end;
end;
ParentHandle = Handle der Form, auf der sich das Label befindet
LabelName = Name des Label-Controls
  Mit Zitat antworten Zitat
Benutzerbild von PinkFloydFan
PinkFloydFan

Registriert seit: 4. Dez 2007
Ort: Straubing
54 Beiträge
 
Delphi 2010 Architect
 
#16

AW: Undokumentierter Sendmessage-Befehl

  Alt 5. Sep 2011, 09:16
Nu wirds aber richtig interessant!!

Werde ich gleich mal antesten!!

Sollte es doch noch eine Lösung geben?? *freu*
  Mit Zitat antworten Zitat
Benutzerbild von PinkFloydFan
PinkFloydFan

Registriert seit: 4. Dez 2007
Ort: Straubing
54 Beiträge
 
Delphi 2010 Architect
 
#17

AW: Undokumentierter Sendmessage-Befehl

  Alt 5. Sep 2011, 09:28
@Morphie:

Danke für deinen Vorschlag!!
Liest sich soweit gut, aaaber:

hier bekomme ich eine Zugriffsverletzung:

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


"Lesen von Adresse 00000009"

Dieser Code scheint nur bei der eigenen Anwendung zu funktionieren.
Sobald man das Handle einer fremden Anwendung angibt, erhält man die Zugriffs-Verletzung

Edit: Ers ma Kaffee zubereiten...

Geändert von PinkFloydFan ( 5. Sep 2011 um 09:31 Uhr)
  Mit Zitat antworten Zitat
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#18

AW: Undokumentierter Sendmessage-Befehl

  Alt 5. Sep 2011, 09:30
vergiss es doch wieder mit meiner Lösung Klappt doch nicht so wunderbar, wie ich gedacht habe
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Undokumentierter Sendmessage-Befehl

  Alt 5. Sep 2011, 23:46
Eigentlich wäre es besser, wenn ihr das Programm neu erstellt.



Wie/warum konnte da jemand eigentlich einfach so alle Quellen zerstören?
(keine Backups )

Es ist eigentlich nicht möglich vorgesehn, Komponenten von extern auszulesen.
und ja, eigentlich gibt es da so Wege, aber die sind kein Zuckerschlecken, da man die RTTI manuell auslesen und die Komponenten/Property/Speicherzuriffe ebenfalls alle manuell zurückverfolgen muß (also alles, was einem die ganzen VCL-Klassen sonst abnehmen).
Auch ist HInstance noch hardgecodet, was natürlich bei allen "verschobenen" Programmen zwangläufig darin enden muß, daß dort nichts gefunden wird.

Was mich aber grade sehr überrascht hat ist, daß Skype (für Windows) wohl doch immernoch in Delphi geschrieben ist.
Code:
$0340F180 TLoginForm:LoginForm
   $0693A490 TLoginControl:{NoName}
      $06943890 TAccessibleComboBox:{NoName}
      $0694B460 TAccessibleEdit:{NoName}


$06B6A630 TZapMainForm:ZapMainForm
   $034DF180 THomeForm:{NoName}
      $06B7A490 TCanvasNavigationPanel:{NoName}
      $06B7B250 THomeBackground:{NoName}
         $06B8B460 TWebAppBrowser:{NoName}
            $06B7B5C0 TWebAppErrorPanel:{NoName}
               $06B8B740 TButton:{NoName}
            $034DF600 TWebBrowserEx:{NoName}
   $06B58200 TPanelButtons:PanelButtons
   $06B79360 TZapCommunicator:Com
   $06B796D0 TMyselfControl:{NoName}
   $06B5F5C0 TConversationsControl:{NoName}
      $06B8ABC0 TAccessibleEdit:{NoName}
      $06B8AEA0 TScrollBar:{NoName}
   $06B79A40 TEmptyCanvas:{NoName}
   $06B79DB0 TSkypeSplitter:{NoName}
   $06B5F980 TDCEmbedBanner:{NoName}
   $06B5FD40 TChromeMenu:ChromeToolbar
      $06B83890 TToolButton:{NoName}
      $06B83A70 TToolButton:{NoName}
      $06B83C50 TToolButton:{NoName}
      $06B83E30 TToolButton:{NoName}
      $06B84010 TToolButton:{NoName}
      $06B841F0 TToolButton:{NoName}
      $06B843D0 TToolButton:{NoName}
      $06B845B0 TToolButton:{NoName}
      $06B84790 TToolButton:{NoName}
   {Fehler}
Das Programm ist in D2010 geschrieben und nutzt die 2010er-RTTI, also mit anderen Delphi-Version könnte es Probleme geben, vorallem mit TControl.Name, da dieses natürlich als Unicode ausgelesen wird.
Außerdem kann es auch zu unstimmigkeiten kommen, da ja die Fremd-Objetke mit der eigenen RTTI interpretiert werden, anstatt mit der Fremden (läßt sich bestimmt auch noch irgendwie lösen).
TControl.ClassName hat Emba allerdings halbwegs abwärtskompatibel gelassen, bzw. sie haben es sich leicht gemacht und die RTTI eigentlich in ANSI (UTF-8) belassen.

Für D2010\XE\XE2 könnte man sowas also vermutlich relativ "leicht" ausbauen, aber darunter wird es echt frickelig.
Miniaturansicht angehängter Grafiken
unbenannt2.png  
Angehängte Dateien
Dateityp: 7z Project5.7z (376,0 KB, 6x aufgerufen)
$2B or not $2B

Geändert von himitsu ( 6. Sep 2011 um 00:01 Uhr)
  Mit Zitat antworten Zitat
gekkorist

Registriert seit: 14. Jan 2007
30 Beiträge
 
#20

AW: Undokumentierter Sendmessage-Befehl

  Alt 6. Sep 2011, 00:36
Kann mir nicht so richtig vorstellen das man es nicht mit Readprocessmemory auslesen kann.
Hattest ja schon geschrieben das du ein mem dump gemacht hattest und sich die Adressen verschieben, aber das ist so gut wie normal. Irgendwann kommt man aber an die Adresse wo die Werte Statisch stehen.. ist aber ebend bissel Arbeit.
Ein starkes Tool um Adressen von "multi level pointers" zu finden könnt ich die Cheatengine empfehlen, wo man sich aber auch erst reinfitzen muss.

gutes Gelingen in deinem Projekt
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 4     12 34      


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 16:37 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