Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Undokumentierter Sendmessage-Befehl (https://www.delphipraxis.net/162760-undokumentierter-sendmessage-befehl.html)

PinkFloydFan 4. Sep 2011 22:20

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:
lFormCaptionHeapAddress = SendMessage(hwnd, VBM_WINDOWTITLEADDR, ByVal 0&, ByVal 0&)
meine Delphi-Lösung:

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!

Mithrandir 4. Sep 2011 22:23

AW: Undokumentierter Sendmessage-Befehl
 
Code passt soweit. Auf welchen Systemen soll das denn laufen und vor allem - wozu brauchst du das?

PinkFloydFan 4. Sep 2011 22:27

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

Luckie 4. Sep 2011 22:35

AW: Undokumentierter Sendmessage-Befehl
 
Moment. Heap? Aus dem Adressraum des eigene Prozesses? Warum so umständlich?

PinkFloydFan 4. Sep 2011 22:39

AW: Undokumentierter Sendmessage-Befehl
 
ja neee :lol:

nicht der eigene..

Labels aus ner fremden Anwendung...

Luckie 4. Sep 2011 23:10

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?

PinkFloydFan 4. Sep 2011 23:16

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..

EWeiss 5. Sep 2011 01:04

AW: Undokumentierter Sendmessage-Befehl
 
Zitat:

aus ner beliebigen Form auslesen kann
Dir ist aber schon klar das diese Sendmessage wenn überhaupt nur mit VB6 Formen (HWND) funktioniert?
"ThunderRT6FormDC"

Code:
'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
gruss

PinkFloydFan 5. Sep 2011 07:02

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??

DeddyH 5. Sep 2011 07:03

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.

PinkFloydFan 5. Sep 2011 07:22

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..

Morphie 5. Sep 2011 07:47

AW: Undokumentierter Sendmessage-Befehl
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von PinkFloydFan (Beitrag 1121698)
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.

DeddyH 5. Sep 2011 07:52

AW: Undokumentierter Sendmessage-Befehl
 
Aber wie kommt man von außen an die Beschriftung? WM_GETTEXT usw. scheiden ja mangels Fensterhandle aus.

PinkFloydFan 5. Sep 2011 08:02

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:
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..

Morphie 5. Sep 2011 08:12

AW: Undokumentierter Sendmessage-Befehl
 
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

PinkFloydFan 5. Sep 2011 08:16

AW: Undokumentierter Sendmessage-Befehl
 
Nu wirds aber richtig interessant!!

Werde ich gleich mal antesten!!

Sollte es doch noch eine Lösung geben?? :thumb: *freu*

PinkFloydFan 5. Sep 2011 08:28

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...

Morphie 5. Sep 2011 08:30

AW: Undokumentierter Sendmessage-Befehl
 
vergiss es doch wieder mit meiner Lösung ;-) Klappt doch nicht so wunderbar, wie ich gedacht habe

himitsu 5. Sep 2011 22:46

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:
$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. :stupid:

Für D2010\XE\XE2 könnte man sowas also vermutlich relativ "leicht" ausbauen, aber darunter wird es echt frickelig.

gekkorist 5. Sep 2011 23:36

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

himitsu 5. Sep 2011 23:49

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:

PinkFloydFan 6. Sep 2011 08:07

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..

Luckie 6. Sep 2011 08:54

AW: Undokumentierter Sendmessage-Befehl
 
Zitat:

Zitat von PinkFloydFan (Beitrag 1122000)
Ubd der hat das Programm mehr oder
weniger in seiner Freizeit gecodet, womit es eigentlich kein Firmeneigentum ist..

Kommt auf die Vereinbarung an, die getroffen wurde.

Zitat:

Tja, und dann kommt da noch ne Frau ins Spiel.. Die des Programmierers.
Den Rest kann man sich ja dann wohl denken..
Ich weiß jetzt nicht, was die frau mit dem Problem zu tun hat und denken, kann ich mir da jetzt auch nichts unbedingt.

Davon mal abgesehen, was versucht du eigentlich zu erreichen? Eventuell gibt es ja eine bessere Möglichkeit.

Viele Grüße, BruceSpringsteenFan.

sirius 6. Sep 2011 09:03

AW: Undokumentierter Sendmessage-Befehl
 
Zitat:

Zitat von PinkFloydFan (Beitrag 1122000)
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..

TDBText ist doch nur ne Ableitung von TCustomLabel. Also müsste alles was für ein Label funktioniert auch für DBTExt klappen.


Viele Grüße, NKOTBFan

PinkFloydFan 6. Sep 2011 09:14

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..

sirius 6. Sep 2011 09:34

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.

PinkFloydFan 6. Sep 2011 09:52

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.

himitsu 6. Sep 2011 10:13

AW: Undokumentierter Sendmessage-Befehl
 
TDBText ist zwar von TCustomLabel abgeleitet, aber holt sich den Text aus dem angehängten DataLink.

PinkFloydFan 6. Sep 2011 10:21

AW: Undokumentierter Sendmessage-Befehl
 
Zitat:

(Außerdem gehört alles hier um Forum Cheffe. Der Braucht das angeblich für seine Weltherrschaft)
btw:

Ich hab letztes Jahr ne Weltreise gemacht..

Aber da fahr ich nicht mehr hin... :-D

sirius 6. Sep 2011 10:40

AW: Undokumentierter Sendmessage-Befehl
 
Zitat:

Zitat von himitsu (Beitrag 1122038)
TDBText ist zwar von TCustomLabel abgeleitet, aber holt sich den Text aus dem angehängten DataLink.

Jep, und wenn im DataLink das Ereignis onChange auftritt, wird automatisch Caption neu gesetzt. Und es scheint ja auch zu funktionieren.

PinkFloydFan 6. Sep 2011 10:48

AW: Undokumentierter Sendmessage-Befehl
 
So.

Muss nun zur Arbeit..:(

Neueste Erkenntnisse dann Morgen..

sirius 6. Sep 2011 12:11

AW: Undokumentierter Sendmessage-Befehl
 
Delphi-Quellcode:
for k:= 0 to Length(Help) do mem.vgl[k-1]:=help[k];
Muss die Schleife nicht von 1 loslaufen?


Zitat:

Muss nun zur Arbeit..
Du machst das für Deinen Chef also jetzt auch in deiner Freizeit?

FredlFesl 6. Sep 2011 13:03

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.

himitsu 6. Sep 2011 13:53

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