C++ Hook Obsługa Okien

0

Witam, mam problem. ;)

Mianowicie, chcę zrobić hooka na MessegeBoxy, ale za ch..iny nie wiem jak się za to zabrać...
Czyli np:

  • Jest program, a mianowicie gra. Jak grze coś nie odpowiada to wywala MessageBox. Tytuł zawsze jest taki sam czyli Error, a dla mnie ważne jest to co jest "w środku" napisane.
    Moje pytanie brzmi:
    Jak założyć hooka, tak aby przechwycić tą wiadomość, odczytać wartość jaka jest przesłana (oprócz tytułu, to co jest napisane w oknie), oraz od razu zamknąć okno. (To ostatnie akurat będę wiedział ;) )

Pozdrawiam i liczę na pomoc.

0

Hook'iem nie przechwycisz zawartości MessageBox()'a, bo MessageBox nie jest komunikatem(raczej) systemowym...

Raczej wątpię aby dało radę odczytać ten tekst, to zależy gdzie jest on przechowywany...

0

MessageBox to zwykle okno dialogowe, tworzone dynamicznie, prawdopodobnie za pomoca DialogBoxIndirectParam (czyli, wlasciwie za pomoca CreateWindowEx).

Po klasie okna tego nie rozpoznasz, co najwyzej po tytule, ewentualnie jeszcze mozesz sprawdzac okna pod katem czy nie zawieraja jednej ze standardowych ikon typowych dla MessageBoxa. Mozesz tez sprobowac zobaczyc jaki modul wywoluje okno, byc moze MessageBoxy pochodza z jakiejs biblioteki systemowej - jezeli tak to jestes w domu (chociaz tu jestem prawie pewien ze otrzymasz tylko program, ktory komunikat wywolal).

Ale jezeli chodzi ci tylko o ta jedna gre to masz sprawe uproszczona, bo wystarczy odfiltrowac okna pod katem nalezacych do tej gdy i pod katem tytulu.

Na razie nic wiecj mi do glowy nie przychodzi..

0

Hmm... Musi coś być ;P
http://www.speedyshare.com/924785992.html
Tutaj jest info o tym messageboxie z WinID.

Czyli co polecacie zrobić, tak -/+ opisać po kolei (jeśli możecie).

Pozdrawiam

0

hooki w c++? hahaha, smieszny jestes [rotfl]

jak chcesz moge ci pomoc zrobic to w usermode.

-OpenProcess / CloseHandle (wiadomo)
-VirtualProtectEx (pamiec user32 jest read-execute)
-VirtualAllocEx (pamiec dla procedury hooka)
-WriteProcessMemory (zapis twojego kodu, oraz podmiana kodu w messageboxie)

pamietaj ze adresy nie musza byc takie same (a nawet dllka nie musi byc zaladowana)
wiec pierw skopiuj z iat adresy to twojego kodu.
Musisz uwzglednic ze sa 2 wersje tej funkcji (MessageBoxA i MessageBoxW).
Najprosciej bedzie ci podmienic ostatnie 3 bajty (retn 0x10)+align (razem 8 bajtow), wtedy w callbacku masz wszystkie argumenty box'a i adres powrotu. Najlepiej zrob do w sposob mov edx,0x12345678 jmp edx, ofc adres bierzesz z tego co zwroci VirtualProtectEx. Pamietaj ze rejestry ebx,ebp,esi,edi musza byc zachowane (no i jeszcze eax, ale to juz twoj hook). nie wiem jak wyglada implementacja tych funkcji pod roznymi windowsami, wiec lepiej sprawdz (no albo parsuj i szukaj retn 0x10).

A jesli chcesz tylko przechwycic dane, zapisac je gdzies i nie wyswietlac okna to jeszcze prostsza sprawa, nadpisujesz od 1wszego bajtu obie procedury, i dla wygody mozesz wyimportowac fopen/fprintf/fclose z msvcrt, uwazaj na stos ofc...
Powodzenia.

0

Znajdujemy okno po tytule , szukamy okien potomnych ,
jeśli znaleziono okno "Static" , pobieramy z niego tekst
Uwaga. Okno zawiera ikonę Static , ten "tekst" trzeba odrzucić
Teraz trzeba pomyśleć w jaki sposób uruchamiać kod szukający
okna , może wystarczy tylko cykliczne wywołanie Timerem , a może nie
:-)
Jak nie ,trzeba rozpoznać jaką funkcją jest tworzone okno , władować
bibliotekę do procesu tworzącego okno i przekierować na własną . Lub sposób jak podał lol1234
Trudniejszy , ale pozwala np.zapobiec wyświetlaniu MessageBoxa ,


char buff[255] ; // bufor na napisy z okna
HWND hButton ;   // Handle Buttona
HWND hWnd ;      // Handle MessageBox-a    

BOOL CALLBACK MyEnumChildProc(HWND hWnd,LPARAM lParam)
{
   if(GetClassName(hWnd,buff,255))
   {
      if(0==lstrcmp(buff,"Static")) // jaśli okno Static
      {                             // pobierz tekst
          SendMessage(hWnd,WM_GETTEXT,(WPARAM)255,(LPARAM)buff);

         /*
          Tu w buff mamy tekst z okien typu Static
          w kolejnych wywołaniach MyEnumChildProc
         */
         /*
          'Tekst' pobrany z Ikony trzeba pominąć
         */

      }
      // łapiemy handle Buttona
      if(0==lstrcmp(buff,"Button"))
      {
         hButton = hWnd ;
      }
   }
   return true ;
}

//...........
//............ Fun wywoływana przez Timer np. co 200 ms
void FindMessageBox(void)
{
 hWnd = FindWindow(NULL,"Error");

 if(NULL != hWnd)
 {
     // znaleziono okno z tytulem "Error"
     // szukamy potomnego Static

    EnumChildWindows(hWnd,MyEnumChildProc,0)  ;

     // Zamykamy okno "Error"

     //SendMessage(hWnd,WM_CLOSE,0,0);
     
     // lub Klikamy w Buttona
    SendMessage(hButton,BM_CLICK,0,0);
 }

}
0

Wszystko wydaje się logiczne. Dzięki. Tylko że kompilatorowi coś odpie..rdziela.
Przy
" EnumChildWindows(hWnd,MyEnumChildProc,0); "

Wywala:
"
[C++ Error] Unit1.cpp(97): E2034 Cannot convert 'int (__stdcall *)(void *,long)' to 'int (__stdcall *)()'
[C++ Error] Unit1.cpp(97): E2342 Type mismatch in parameter 'lpEnumFunc' (wanted 'int (__stdcall *)()', got 'int (__stdcall *)(void *,long)')
"
W czym problem?;/

Pozdrawiam

0

Jeśli piszesz w Borlandzie
daj przed wszystkimi (na początku pliku) nagłówkami :

#define STRICT 
0

Dodałem i nadal to samo. Piszę w BCB6.

Pozdrawiam i dziękuję za wszelką pomoc. ;)

0

g.. prawda :

//---------------------------------------------------------------------------
#define STRICT
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
char buff[255] ; // bufor na napisy z okna
HWND hButton ;   // Handle Buttona
HWND hWnd ;      // Handle MessageBox-a

BOOL CALLBACK MyEnumChildProc(HWND hWnd,LPARAM lParam)
{
   if(GetClassName(hWnd,buff,255))
   {
      if(0==lstrcmp(buff,"Static")) // jaśli okno Static
      {                             // pobierz tekst
          SendMessage(hWnd,WM_GETTEXT,(WPARAM)255,(LPARAM)buff);

         /*
          Tu w buff mamy tekst z okien typu Static
          w kolejnych wywołaniach MyEnumChildProc
         */
         /*
          'Tekst' pobrany z Ikony trzeba pominąć
         */

      }
      // łapiemy handle Buttona
      if(0==lstrcmp(buff,"Button"))
      {
         hButton = hWnd ;
      }
   }
   return true ;
}

//...........
//............ Fun wywoływana przez Timer np. co 200 ms
void FindMessageBox(void)
{
 hWnd = FindWindow(NULL,"Error");

 if(NULL != hWnd)
 {
     // znaleziono okno z tytulem "Error"
     // szukamy potomnego Static

    EnumChildWindows(hWnd,MyEnumChildProc,0)  ;

     // Zamykamy okno "Error"

     //SendMessage(hWnd,WM_CLOSE,0,0);

     // lub Klikamy w Buttona
    SendMessage(hButton,BM_CLICK,0,0);
 }

}
//---------------------------------------------------------------------------

Masz czysty kod Form1 , bez STRICT się nie kompiluje ,Build jeszcze raz wszystko ...

Jedzie na BCB 6 i jest ok , nie wkurzaj mnie , ,,,,

0

? Rzeczywiście działa. Nie wiem dlaczego mi nie kompilowało. Dziękuję.

Pozdrawiam

0

No i kod wrzuć do jakiegoś Timera Funkcję FindMessageBox , poglądowo możesz sobie
dać na Form1 Memo do Enum dodaj kod wpisujący zawartość Box :

BOOL CALLBACK MyEnumChildProc(HWND hWnd,LPARAM lParam)
{
   if(GetClassName(hWnd,buff,255))
   {
      if(0==lstrcmp(buff,"Static")) // jaśli okno Static
      {                             // pobierz tekst
          SendMessage(hWnd,WM_GETTEXT,(WPARAM)255,(LPARAM)buff);
     
          Form1->Memo1->Lines->Add(buff) ;  // <<==============
      
         /*
          Tu w buff mamy tekst z okien typu Static
          w kolejnych wywołaniach MyEnumChildProc
         */
         /*
          'Tekst' pobrany z Ikony trzeba pominąć
         */

      }
      // łapiemy handle Buttona
      if(0==lstrcmp(buff,"Button"))
      {
         hButton = hWnd ;
      }
   }
   return true ;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1