Undokumentierter Sendmessage-Befehl
Moin liebe Delphi-Gemeinde
bin immer noch am übersetzen eines VB-Codes und hänge nun fest. Folgende Zeile macht mir Kopfzerbrechen: in VB:
Code:
meine Delphi-Lösung:
lFormCaptionHeapAddress = SendMessage(hwnd, VBM_WINDOWTITLEADDR, ByVal 0&, ByVal 0&)
Delphi-Quellcode:
lFormCaptionHeapAddress:=SendMessage(hwnd, VBM_WINDOWTITLEADDR, 0, 0);
VBM_WINDOWTITLEADDR soll angeblich ne undokumentierte Konstante mit einem Wert von $1091 sein und sollte die Adresse der Form-Caption im Heap liefern.. bei mir leider immer 0.. Hwnd ist das Handle der Form.. Hat das ByVal irgendwas zu sagen?? Kennt jemand diese Abfrage, und wenn ja, wie habt ihr das gelöst?? Danke! |
AW: Undokumentierter Sendmessage-Befehl
Code passt soweit. Auf welchen Systemen soll das denn laufen und vor allem - wozu brauchst du das?
|
AW: Undokumentierter Sendmessage-Befehl
das stammt aus ner VB-Routine, mit der man angeblich Labels aus ner beliebigen Form auslesen kann..
Zu finden unter: http://www.codeguru.com/forum/archiv.../t-304429.html |
AW: Undokumentierter Sendmessage-Befehl
Moment. Heap? Aus dem Adressraum des eigene Prozesses? Warum so umständlich?
|
AW: Undokumentierter Sendmessage-Befehl
ja neee :lol:
nicht der eigene.. Labels aus ner fremden Anwendung... |
AW: Undokumentierter Sendmessage-Befehl
Such mal nach WM_GETTEXT. Allerdings bei Delphi Anwendungen funktioniert das nicht. Oder suchst du gerade dafür eine Lösung?
|
AW: Undokumentierter Sendmessage-Befehl
Moin Luckie!
WM_Gettext ist mir bekannt, funktioniert jedoch bei Labels nicht, da diese bekanntlich kein Handle besitzen. Ich hab mir schon nen Wolf gesucht, wie ich Labels aus ner fremden Applikation auslesen kann, aber nur der obige Link mit dem VB-Code scheint ne vernünftige Lösung zu sein.. |
AW: Undokumentierter Sendmessage-Befehl
Zitat:
"ThunderRT6FormDC"
Code:
gruss
'Make sure we are working with a VB Form hWnd
sClass = Space(256) lRet = GetClassName(hwnd, sClass, 255) sClass = Left(sClass, lRet) If Not sClass = "ThunderRT6FormDC" Then MsgBox "This function only works on VB RunTime 6 Forms ThunderFormRT6DC" Exit Sub End If |
AW: Undokumentierter Sendmessage-Befehl
Guten Morgen!
@ EWeiss: Das war mir schon klar.. Ich bin eben sehr optimistisch :glaskugel: und hoffte, das man das auch für ne Delphi-Form verwenden könnte.. Aber so wie's aussieht kann ich das auch vergessen.. Hintergrund des Ganzen ist, dass wir in der Firma ein Hypersuperoberwichtiges Programm am Laufen haben, dessen Quellcode leider von einem ehemaligen Mitarbeiter mutwillig zerstört wurde und somit nicht mehr verfügbar ist, auch nicht in Code-Fragmenten. Das Proggi tut ja seinen Dienst, und nun sollten einige Erweiterungen dazu geschrieben werden, um das Handling dieses Proggs etwas zu erleichtern. Allerdings sind alle Text-Ausgaben, die das Programm tätigt, nicht in Edits oder Memos (Leider, denn dann wär's ja ein Leichtes) sondern in Labels... Und das ist das Problem. Um die Sache "fernzusteuern" muss ich den Inhalt dieser Labels kennen. 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... Die grosse Frage lautet also: Wie komme ich also an die Captions diese Label?? |
AW: Undokumentierter Sendmessage-Befehl
Wenn es wirklich Labels sind, sieht es schlecht aus. Bei StaticText gäbe es noch die Möglichkeit, die Fensterhandles zu ermitteln und zu schauen, was da was ist.
|
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 |
AW: Undokumentierter Sendmessage-Befehl
ReadProcessMemory ... Was denkst du, wie ich den Speicher rüberkopiere? :zwinker:
Aber das Problem hierbei ist, erstmal rauszubekommen wo sich was befindet. Es gibt eben keine direkte statische Zuordnung zwischen Handle (HWND) und TControl ... ist alles schön dynamisch und schön verschachtelt. Und beim TLabel gibt es noch nichtmal ein Handle, weswegen man sich dort durch noch mehr verschachtelungen wurschteln muß. Bei den anderen Controls kann man ja leicht an den Text kommen, da sich das HWND suchen und dann über die WinAPI (z.B. WM_GETTEXT) dieser auslesen läßt, aber z.B. dem TLabel kannst du keine Message schicken. Wenn ich dir eine hochauflösende Luftaufnahme von Europa gebe, dann wirst du es dennoch schwer haben mich darauf zu finden. :wink: |
AW: Undokumentierter Sendmessage-Befehl
Guten Morgen liebe Delphi-Gemeinde!
@ Himitsu: Tja, das ist das Ergebnis wenn der Scheffe solche Sachen nur einem einzigen Mann überlässt, weil er Zitat "Vollstes Vertrauen" hat. Ubd der hat das Programm mehr oder weniger in seiner Freizeit gecodet, womit es eigentlich kein Firmeneigentum ist.. Tja, und dann kommt da noch ne Frau ins Spiel.. Die des Programmierers. Den Rest kann man sich ja dann wohl denken.. Dein Programm Form5 ist ja die Wucht, aber so richtig weiterhelfen tuts mir eigentlich nicht :( Wozu dienen die Komponenten auf Panel1?? Ich hab gestern auf Maloche das Proggie mit nem Resource-Viewer (nicht mit ResHacker, wie von Morphie vorgeschlagen, weil der abstürzte, wenn ich die betreffende Form öffnen wollte sondern mit XN Resource Editor) gecheckt, und jetzt kommts noch schlimmer: Das was ich für Labels hielt, sind in Wirklichkeit TDBText Objekte... die haben ja keine Caption oder nen Text.. bim momentan etwas ratlos und kurz vorm aufgeben..... :cry::cry::cry::cry::cry: glaube ich brauche bald mal nen Reset :cheers: Obigen Quelltext von Sirius hab ich etwas abgewandelt, und man kann damit tatsächlich sämtliche Labels (wenn der Name bekannt ist) auslesen.. Aber jetzt gehts plötzlich um TDBText... Edit: Hab grade festgestellt daß TDBText doch ne Caption haben... lässt sich schreiben und lesen. Taucht nur nicht in der OH auf.. |
AW: Undokumentierter Sendmessage-Befehl
Zitat:
Zitat:
Davon mal abgesehen, was versucht du eigentlich zu erreichen? Eventuell gibt es ja eine bessere Möglichkeit. Viele Grüße, BruceSpringsteenFan. |
AW: Undokumentierter Sendmessage-Befehl
Zitat:
Viele Grüße, NKOTBFan |
AW: Undokumentierter Sendmessage-Befehl
Hallo Sirius!!
Von dir stammt also dieses schöne Stückchen Code!! Ich hoffe du hast nichts dagegen dass ich dein geistiges Eigentum in mein Proggi einbaue?? *liebfrag* Wie kommt man auf sowas bzw. woher hast du solche Informationen?? edit: @Luckie (sorry): Frau des Prgrammierers---Scheffe > Bett > Programmierer sauer > Programmierer will sich rächen usw usw usw Edit: Aber das erzählt man sich nur so.. gerüchteweise... Ich hab Sirius' Code mal mit DBText probiert, und es funzt!! Wichtig dabei ist nur, dass der Name des Labels exakt stimmt, d.h. auch Groß- und Kleinschreibung!! Meine Quick and Dirty Lösung kann ich ja mal anhängen, wenn Interesse daran besteht.. |
AW: Undokumentierter Sendmessage-Befehl
Klar kannst du das verwenden.
(Außerdem gehört alles hier um Forum Cheffe. ;) Der Braucht das angeblich für seine Weltherrschaft) Mein Code-Beispiel, mit dem ich das gelernt habe, kam seinerzeit von Hagen: http://www.delphipraxis.net/11550-su...t-das-net.html Veröffentlichen wäre nicht schlecht. Du hast ja wahrscheinlich auch hier und da noch etwas geändert. Aber wie oft, willst du derartig "schmutzige" Tricks noch anwenden. Du brauchst doch sicher mehr als ein TDBText.Caption aus dem anderen Programm. Willst du nicht vielleicht doch schauen, ob du bspw. die SQL-Abfragen mit dem Ressourcen-Hacker rausbekommst. |
AW: Undokumentierter Sendmessage-Befehl
Liste der Anhänge anzeigen (Anzahl: 1)
Also dann:
Aber wiegesagt: Quick'n Dirty..
Delphi-Quellcode:
unit readlabel;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, DBCtrls; 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) Button1: TButton; Button2: TButton; Edit1: TEdit; Edit2: TEdit; Label4: TLabel; Edit3: TEdit; Label1: TLabel; Label2: TLabel; DBText1: TDBText; Button3: TButton; Label3: TLabel; procedure Button2Click(Sender: TObject); procedure Button1Click(Sender: TObject); procedure GetMyCaption(var msg:TMessage);message mymsg+1; procedure Button3Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private-Deklarationen } myhandle:hwnd; public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} function injectThread(memory:Pmemory):integer; stdcall; 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 p:=pointer(integer(pm^)+4); p:=pointer(integer(p^)+4*a); pi:=p; 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; break; end; end; end; end; memory^.Postmessage(memory^.backwnd,memory^.backmsg,wparam,lparam); result:=0; 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; help:string; k:Integer; begin try myhandle:=strtoint(Edit1.Text); except myhandle:=findwindow(nil,PChar(Edit1.Text)); end; if myhandle=0 then exit; mem.backwnd:=self.Handle; mem.backmsg:=mymsg; mem.watchwnd:=myhandle; mem.count:=6; mem.vgl:=''; help:=Edit2.Text; for k:= 0 to Length(Help) do mem.vgl[k-1]:=help[k]; mem.vgllength:=Length(Help); mem.SearchType:=sCaption; size:=integer(@endpoint)-integer(@injectThread); move(injectthread,mem.thread,size); lib:=getmodulehandle('user32.dll'); mem.Postmessage:=getprocaddress(lib,'PostMessageA'); mem.getwindowlong:=getprocaddress(lib,'GetWindowLongA'); lib:=getmodulehandle('kernel32.dll'); mem.exitthread:=getprocaddress(lib,'ExitThread'); getwindowthreadprocessid(myhandle,@processid); process:=openprocess(PROCESS_ALL_ACCESS,false,processid); procmem:=virtualallocex(process,nil,sizeof(Tmemory),MEM_COMMIT,PAGE_EXECUTE_READWRITE); writeprocessmemory(process,procmem,@mem,sizeof(TMemory),tmp); thread:=createremotethread(process,nil,0,@procmem.thread,procmem,0,threadid); waitforsingleobject(thread,infinite); closehandle(thread); virtualfreeex(process,procmem,0,mem_decommit); closehandle(process); end; procedure TForm1.GetMyCaption(var msg:TMessage); var process,processID,tmp:cardinal; s:string; begin if myhandle=0 then exit; 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); Label4.Caption:= 'Caption von "'+Edit2.Text+'" in Fenster "'+Edit1.Text+'":'; Edit3.Text:=s; end; procedure TForm1.Button3Click(Sender: TObject); begin edit3.Text:=dbtext1.Caption; end; procedure TForm1.FormCreate(Sender: TObject); begin DBText1.Caption:='Test Xaverl'; end; end. |
AW: Undokumentierter Sendmessage-Befehl
TDBText ist zwar von TCustomLabel abgeleitet, aber holt sich den Text aus dem angehängten DataLink.
|
AW: Undokumentierter Sendmessage-Befehl
Zitat:
Ich hab letztes Jahr ne Weltreise gemacht.. Aber da fahr ich nicht mehr hin... :-D |
AW: Undokumentierter Sendmessage-Befehl
Zitat:
|
AW: Undokumentierter Sendmessage-Befehl
So.
Muss nun zur Arbeit..:( Neueste Erkenntnisse dann Morgen.. |
AW: Undokumentierter Sendmessage-Befehl
Delphi-Quellcode:
Muss die Schleife nicht von 1 loslaufen?
for k:= 0 to Length(Help) do mem.vgl[k-1]:=help[k];
Zitat:
|
AW: Undokumentierter Sendmessage-Befehl
Neu programmierern wurde ja schon oft ins Spiel gebracht. Ich kann doch als Firma keine Blackbox haben, die ich nur mit irgendwelchen Tricks erweitern kann... Nur eine Neuerstellung der Anwendung ist nachhaltig.
Und wenn der Mitarbeiter das Programm wirklich in seiner Freizeit entwickelt haben sollte, dann stellt sich die Frage nach der Rechtmäßigkeit der Weiterverwendung sowieso. Desweiteren würde ich mit dem Herren in Verhandlungen treten. Wie gesagt: Wenn er es in seiner Freizeit entwickelt hat, dann steht ihm eine entsprechende Vergütung zu. Der Chef ist ja wohl nur blöd, wenn er sich auf so etwas einlässt (also ein Programm zu verwenden, dass in der Freizeit geschrieben wurde). Ich meine, man sollte mit dem Kerl reden, und zwar nach dem Motto: "Tolles Programm, wir zahlen auch angemessen. Aber wir können es aber auch neu entwickeln, wenn Du uns blöd kommst" Mehr als unverschämte Forderungen kann er auch nicht stellen und nach dem Gespräch weiss man, was zu tun ist. Aber diese Labelausleserei ist ja wohl der größte Blödsinn, vor allen Dingen von TDBLabel... Woher kommen die Daten denn? Doch sicherlich aus einer DB... Da die Anwendung von einer Person entwickelt wurde, sollte sich sich auch von 1-2 Personen in angemessener Zeit nachstellen lassen. |
AW: Undokumentierter Sendmessage-Befehl
Mit welcher Delphi-Version wurde das eigentlich mal entwickelt?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:41 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