MessageCodes umwandeln



  • Hallo,
    ich habe ein Programm geschrieben, dass die bei einem Fenster eines Fremden Prozesses ankommenden Nachrichten (wie WM_PAINT, WM_CHAR, WM_SETFOCUS,...[definiert in WinUser.h]) mitloggt (durch dllinjection und subclassing des Hauptfensters).

    das funktioniert auch soweit und in der log-datei landen brav alle empfangenen messages 🙂

    Das einzige Problem bei der Sache ist, dass dort natürlich nur die Codes für die Messages ankommen( also zB 0x0312 für WM_HOTKEY, oder 0x0007 für WM_SETFOCUS);

    Nur wie kann ich diese Codes wieder umwandeln in die Nachrichten( zB 0x0007 -> WM_SETFOCUS)?

    die Tatsache, dass in der log nur die Codes ankommen liegt daran, wie ich es in der neuen WndProc mitlogge:

    (vereinfachtes Beispiel):

    ofstream os("C://test//test.log");
    
    LRESULT CALLBACK neueWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
    {
    os<<message<<endl;
    }
    

    (natürlich wird etwas mehr geloggt, aber als beispiel für die messagecodes reicht das)

    Aber wie kriegt man aus diesen Codes nun wieder die Messages? Gibts da irgendeine Funktion die codes zB in einen string oder ein char-array oder so umwandelt? (also 0x0007 nach "WM_SETFOCUS")

    danke schonmal,
    andi01.



  • Die Codes SIND die Nachrichten.

    WM_SETFOCUS ist nur eine Krücke um die menschliche Schwäche beim Merken von Zahlen auszugleichen.

    Wenn du dir mal die Header durchschaust wirst du irgendwo eine Zeile wie:

    #define WM_SETFOCUS 0x0007
    

    finden. Die sagt dem Compiler nur: Ersetze alle WM_SETFOCUS durch 0x0007.

    Wenn du also die Codes wieder in "Nachrichten" umwandeln willst musst du das selbst bewerkstelligen.



  • Wenn DU es zu Debug-Zwecken machen willst, kannst Du einfach auch im Watch-WIndow des Debuggers z.B: schreiben:

    12,wm

    Dann wird die 12 auch als WM_* angezeigt... (oder natürlich eine Variable anstelle der 12 verwenden).



  • ich will (bzw. muss) das deshalb machen weil in der log-datei eben nur die codes wie 0x0007 statt WM_SETFOCUS ankommen, und wenn ich die zugehörige message wissen will muss ich jeden code einzeln nachsehen...

    ich dachte eigentlich da gibts ähnlich funktionen wie zB bei den VirtualKeyCodes:

    da gibts ja auch sowas:

    int keycode=VkKeyScan('a');
    

    dasn problem dabei ist dass da so viele messages ankommen dass ich die unmöglich alle selber nachschauen kann.

    das problem kommt eigentlich daher dass bei meiner aktuellen log-methode eben nur diese codes mitgeschrieben werden:

    ofstream os("C://test//test.txt");
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
    {
    os<<message<<endl;
    }
    

    und dann stehen (vereinfacht) eben in meiner log-datei nur

    logdatei schrieb:

    0x0007
    0x0008
    0x0007
    [...]

    und ich bräuchte jetzt einen weg daraus quasi wieder

    log schrieb:

    WM_SETFOCUS
    WM_KILLFOCUS
    WM_SETFOCUS

    zu machen^^

    mir fällt nur gerade kein Weg ein wie ich das machen könnte...

    Jochen Kalmbach schrieb:

    Wenn DU es zu Debug-Zwecken machen willst

    ich mache das ganze weil ich mir mal anschaun will welche nachriichten so verschickt werden wenn man zB Buttons klickt, das fenster verschiebt ect.
    (und natürlich einfach auch zu Übungszwecken 😃 )

    edit: ach nur mal so nebenbei, weiß jemand was der Code 0x0132 bedeutet? ich kann ihn in WinUser.h einfach nicht finden 🙄 (WM_CTLCOLORMSGBOX ist es leider nicht)

    lg,
    andi01.



  • Da bräuchtest du dann wohl ne map



  • Ich würde sagen, du machst das selber, da es meines Wissen keine eigene Funktion dafür gibt..
    Also einfach beim bekommen der MessageCodes zB in einem Array nachschauen welche Message diesem Code gehört, dann einfach ersetzen...
    Sollte denke ich mal nicht allzu schwer sein, als nur Tipparbeit 😃



  • das wird dann aber eine ziemlich große map bzw ein großes array wenn ich mir mal anschaue wie viele messages in der winuser.h definiert sind!

    Winuser.h hat ja nur schlappe 13.000 Zeilen 😃 (selbst wenn das nicht alles messages sind sind das doch seehr viele)

    weiß eigentlich jemand was 0x0132 heißt? ich finde das nirgends in WinUser.h (WM_CTLCOLORMSGBOX ist es leider nicht) 🙄

    lg,
    andi01.



  • In spyxx.exe muss ja so eine Map drin sein... aber an die wirst Du vermutlich nicht so einfach rankommen... muss doch mal IDA Pro anschmeissen...



  • Aber gibt es nicht nur etwa 200 Nachrichten ??
    Stand glaub ich im Petzold.
    Also nur die WM_xxx Nachrichten...



  • kann sein, aber es kommen ja noch weitere dazu... zumbeispiel die wichtigsten Messages um Childwindows zu steuern (zB BM_... , BN_... für buttons), da die meisten Fenster ja auch einige childs haben wie Buttons, Checkboxen, Radiobuttons, Textboxen,... da kommen auch noch mal viele dazu^^

    denn diese nachrichten werden ja auch (zumindest teilweise) an das parent geschickt.

    zusammen sind das dann so viele, dass ich sie in realistischem Zeitaufwand unmöglich alle abtippen kann 😞

    (aber auch eine Liste für alle WM... wäre schonmal hilfreich)

    lg,
    andi01.



  • andi01 schrieb:

    zusammen sind das dann so viele, dass ich sie in realistischem Zeitaufwand unmöglich alle abtippen kann 😞

    Was aber nichts an der Tatsache ändert, dass Windows dafür keine Funktion bereitstellt und du höchstens bei Google weiterkommst. 🙂



  • abtippen? nimm doch grep oder so



  • so, ich habe immerhin schonmal eine (hoffentlich wenigstens komplette) Liste aller existierenden Messages gefunden:
    http://wiki.winehq.org/List_Of_Windows_Messages

    jetzt muss ich die nur noch so weit kriegen, dass ich gezielt nach Werten darin suchen kann. Ich werde mir morgen mal in Ruhe einen Weg überlegen wie ich das am besten anstelle weil die liste für arrays etc. vermutlich zu lang ist...

    ist sie denn wenigstens vollständig oder fehlern messages?

    lg,
    andi01.



  • lade sie in einen speicher und durchsuch sie, bau die datei einfach zb wie folgt auf:
    das DateiFormat, vorschlag:
    Byte:
    FF FF = Word 0xFFFF als trennzeichen
    xx xx = Word Als länge der Char, bzw länge der MessageCodes Beschreibung
    xx xx = Message Codes als HEX
    xx xx xx ... = Bezeichnung der MessageCodes in ASCII;

    dann lädst du die gesammte datei in den speicher und dursuchst den buffer!!



  • Warum so kompliziert? Man kann doch auch einfach ein Array benutzen. Der Lookup ist deutlich einfacher.



  • nimm ein switch/case!



  • buntehaare schrieb:

    lade sie in einen speicher und durchsuch sie

    das geht wegen der performance nicht, denn wenn man zB das Fenster so an den Bildschirmrand schiebt, dass es nur noch teilweise sichtbar ist und wieder richtung mitte zieht kommen schon mal 50 WM_PAINTs und andere nachrichten pro sekunde.
    es sollte ziemlich unmöglich sein, eine Liste mit mehreren tausend einträgen 50 mal pro sekunde durchzugehen und die codes dabei umzurechnen(da dürfte einmal komplette durchsuchen und umrechnen max. 5-10ms dauern!) [jenachdem wieviele einträge es genau sind, die sprünge machen es ziemlich schlecht zählbar^^].

    bitsch schrieb:

    nimm ein switch/case!

    das wäre mit der Performance zwar nahezu perfekt aber ich kann unmöglich alles abtippen 😞

    O.o schrieb:

    Warum so kompliziert? Man kann doch auch einfach ein Array benutzen. Der Lookup ist deutlich einfacher

    Das Problem eines Arrays ist, dass die werte durchgehend besetzt sein müssen:

    z.B. machen die nachrichtencodes in den dezimalwerten sprünge:

    Liste schrieb:

    84=WM_USERCHANGED
    85=WM_NOTIFYFORMAT
    123=WM_CONTEXTMENU

    und das geht öfter so... in einem standard-array kann ich aber nicht einfach lücken lassen 😞

    ich denke es wäre am einfachsten eine std::map zu verwenden, oder gibt es bessere Alternativen?

    lg,
    andi01.



  • Hier ein Beispiel wie man es einfach machen kann ohne das man den Wert der Nachricht im Code als Zahl schreiben muss.

    #define WORDCASE(w) case w: return _T(#w)

    static const TCHAR *printable_servicecontrol(DWORD dwControl)
    {
    	switch (dwControl)
    	{
    	  WORDCASE(SERVICE_CONTROL_STOP);
    	  WORDCASE(SERVICE_CONTROL_PAUSE);
    	  WORDCASE(SERVICE_CONTROL_CONTINUE);
    	  WORDCASE(SERVICE_CONTROL_INTERROGATE);
    	  WORDCASE(SERVICE_CONTROL_SHUTDOWN);
    	  WORDCASE(SERVICE_CONTROL_PARAMCHANGE);
    	  WORDCASE(SERVICE_CONTROL_NETBINDADD);
    	  WORDCASE(SERVICE_CONTROL_NETBINDREMOVE);
    	  WORDCASE(SERVICE_CONTROL_NETBINDENABLE);
    	  WORDCASE(SERVICE_CONTROL_NETBINDDISABLE);
    
    	  default: return _T("SERVICE_CONTROL_???");
    	}
    }
    


  • hm also zB 0x0007 ist nach meiner liste als WM_SETFOCUS definiert, deine Funktion sagt aber SERVICE_CONTROL_NETBINDADD 😕

    also es sollen eigentlich die codes für die Windows-Nachrichten in Text "umgewandelt" werden.

    zb. 0x0007->WM_SETFOCUS
    0x0008->WM_KILLFOCUS
    ...

    aber gibt es da auch so eine Funktion? das würde mir nämlich sehr viel Arbeit ersparen 😃
    ganau sowas bräuchte ich für diese codes, das wäre perfekt 🙂

    edit: link zu Liste: http://wiki.winehq.org/List_Of_Windows_Messages

    also mein aktueller Ansatz ist die Liste in eine txt-datei zu kopieren (das geht ja schnell), zu beginn des Programms einmalig in eine globale map einzulesen (bei der der dezimalwert der key-wert ist) und zur laufzeit unter den dezimalwerten mit fast perfekter performance die Nachrichten umzuwandeln...

    oder kann man das noch geschickter oder besser lösen?

    lg,
    andi01.



  • oh mann das war ein BEISPIEL wie du es machen könntest für deine Nachrichten


Anmelden zum Antworten