![]() |
AW: Undokumentierter Sendmessage-Befehl
Guten Morgen DeddyH!
Static Labels sind auf keinen Fall. :cry: 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.. |
AW: Undokumentierter Sendmessage-Befehl
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
![]() |
AW: Undokumentierter Sendmessage-Befehl
Aber wie kommt man von außen an die Beschriftung? WM_GETTEXT usw. scheiden ja mangels Fensterhandle aus.
|
AW: Undokumentierter Sendmessage-Befehl
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:
Natürlich muss dieser Source noch entsprechend aufbereitet werden und einige Sachen entfallen, aber das Prinzip funktioniert..
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. |
AW: Undokumentierter Sendmessage-Befehl
das hier sollte wohl auch schon reichen:
Delphi-Quellcode:
ParentHandle = Handle der Form, auf der sich das Label befindet
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; LabelName = Name des Label-Controls |
AW: Undokumentierter Sendmessage-Befehl
Nu wirds aber richtig interessant!!
Werde ich gleich mal antesten!! Sollte es doch noch eine Lösung geben?? :thumb: *freu* |
AW: Undokumentierter Sendmessage-Befehl
@Morphie:
Danke für deinen Vorschlag!! Liest sich soweit gut, aaaber: hier bekomme ich eine Zugriffsverletzung:
Delphi-Quellcode:
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... |
AW: Undokumentierter Sendmessage-Befehl
vergiss es doch wieder mit meiner Lösung ;-) Klappt doch nicht so wunderbar, wie ich gedacht habe
|
AW: Undokumentierter Sendmessage-Befehl
Liste der Anhänge anzeigen (Anzahl: 2)
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 :zwinker: ) 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. :shock:
Code:
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.
$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} 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. :stupid: Für D2010\XE\XE2 könnte man sowas also vermutlich relativ "leicht" ausbauen, aber darunter wird es echt frickelig. |
AW: Undokumentierter Sendmessage-Befehl
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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:58 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