Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Obsługa wiadomości użytkownika dynamicznie
#1
W ten sposób można dynamicznie przechwytywać funkcje zdarzeń usermsg, więc nie trzeba przechwytywać "pfnHookUserMsg" w celu przechwycenia wskaźników funkcji, co oczywiście byłoby problemem, gdybyś chciał przechwycić funkcje po zarejestrowaniu wszystkich komunikatów użytkownika.       Kod:   // Demontaż funkcji cl_enginefuncs_s :: pfnHookUserMsg 0383AA50 55 PUSH EBP; Kopia zapasowa EBP na stosie 0383AA51 8BEC MOV EBP, ESP; Skopiuj ESP do EBP, ustawianie wskaźnika ramki stosu ... 0383AA61 8B55 0C MOV EDX, DWORD PTR SS: [EBP + C]; Kopiuj funkcję argumentu 2 (pfnUserMsgHook pfn) do EDX 0383AA64 8B45 08 MOV EAX, DWORD PTR SS: [EBP + 8]; Kopiuj argument funkcji 1 (znak * szMsgName) do EAX 0383AA67 52 PUSH EDX; Wciśnij EDX na stos jako argument funkcji 0383AA68 50 PUSH EAX; Wciśnij EAX na stos jako argument funkcji 0383AA69 E8 32F90000 CALL hw. 0384A3A0; Funkcja rejestracji połączenia 0383AA6E 83C4 10 ADD ESP, 10; Dodaj 0x10 do ESP, aby zwolnić miejsce na stosie ... // Adres początkowy funkcji rejestracji 0384A3A0 55 PUSH EBP; Kopia zapasowa EBP na stosie 0384A3A1 8BEC MOV EBP, ESP; Skopiuj ESP do EBP, ustaw konfigurację wskaźnika stosu 0384A3A3 53 PUSH EBX; Kopia zapasowa EBX na stosie 0384A3A4 8B5D 0C MOV EBX, DWORD PTR SS: [EBP + C]; Funkcja kopiowania (pfnUserMsgHook pfn) do EBX 0384A3A7 56 PUSH ESI; Kopia zapasowa ESI na stosie 0384A3A8 8B35 6C9D9903 MOV ESI, DWORD PTR DS: [3999D6C]; Skopiuj adres do pierwszego elementu usermsg_s. Komunikaty użytkownika są traktowane jako lista połączona 0384A3AE 57 PUSH EDI; Backup EDI na stosie 0384A3AF 33FF XOR EDI, EDI; Wyczyść bity EDI 0384A3B1 85F6 TEST ESI, ESI; Wykonaj operację testową, aby sprawdzić, czy wskaźnik nie ma wartości NULL (następna instrukcja) 0384A3B3 74 24 JE SHORT hw. 0384A3D9; Jeśli NULL przeskoczy do części obsługującej obudowę 0384A3B5 8B4D 08 MOV ECX, DWORD PTR SS: [EBP + 8]; Kopiuj funkcję argument 1 (znak * szMsgName) do ECX 0384A3B8 8D46 08 LEA EAX, DWORD PTR DS: [ESI + 8]; Przesunięcie obciążenia do ciągu nazwy msg bieżącego elementu do EAX 0384A3BB 50 PUSH EAX; Wciśnij EAX na stos jako argument funkcji (ciąg 1) 0384A3BC 51 PUSH ECX; Wciśnij ECX na stos jako argument funkcji (ciąg 2) 0384A3BD E8 6EE90000 CALL hw. 03858D30; Funkcja połączeń do porównania ciągów 0384A3C2 83C4 08 ADD ESP, 8; Dodaj 0x08 do ESP, aby zwolnić przestrzeń stosu przestrzeni argumentów 0384A3C5 85C0 TEST EAX, EAX; Porównaj operację testową, aby sprawdzić, czy wartość wyniku wynosi 0 (= łańcuchy są zgodne) 0384A3C7 75 09 JNZ SHORT hw. 0384A3D2; Jeśli łańcuchy są równym skokiem do części, która obsługuje ten przypadek ... 0384A3D2 8B76 18 MOV ESI, DWORD PTR DS: [ESI + 18]; Skopiuj wartość następnego elementu wskaźnika bieżącego elementu do ESI, aby przejść do następnego wpisu 0384A3D5 85F6 TEST ESI, ESI; Wykonaj operację testową, aby sprawdzić, czy wskaźnik nie jest NULL 0384A3D7 ^ 75 DC JNZ SHORT hw. 0384A3B5; Jeśli nie NULL przejście do pętli zacznie obsługiwać następny element ...     cpp:   // ================================================ ====================== struct usermsg_s {int iMsgId; unsigned int dwNieznany; char szMsg [16]; usermsg_s * pNext; pfnUserMsgHook pfn; }; // ================================================ =================================================== =============================================== PfnUserMsgHook HookUserMessage ( const char * pszMsgName, pfnUserMsgHook pfnCallbackFunction) {// Hak wiadomości użytkownika, jeśli ((! pszMsgName) || (! pfnCallbackFunction)) zwraca NULL; // Pobierz pierwszy element usermsg_s * pElement = GetFirstUserMsgElement (); if (! pElement) zwraca NULL; while (pElement) {// Gdy wskaźnik nie ma wartości NULL, jeśli (strcmp (pElement -> szMsg, pszMsgName) == 0) {// Jeśli wiadomość została znaleziona pfnUserMsgHook pOrig = pElement -> pfn; // Oryginalna funkcja kopii zapasowej pElement -> pfn = pfnCallbackFunction; // Zamień adres funkcji return pOrig; } PElement = pElement -> pNext; // Przejdź do następnego elementu} return NULL; } // =============================================== ================================================== ============================================= usermsg_s * GetFirstUserMsgElement (void ) {// Ca
Reply
#2
Dobra robota!
Reply
#3
miła robota sk0r. zrobić to b4: P heres ze wzorem, jeśli ktoś tego potrzebuje później: cpp: CUserMessageHook * CUserMsg :: GetFirstUserMsg () {statyczny DWORD dwFirstUserMsg = 0; if (! dwFirstUserMsg) {dwFirstUserMsg = g_Util. FindPattern ("hw.dll", (BYTE *) "\ x8B \ x35 \ x00 \ x00 \ x00 \ x00 \ x83 \ xC4 \ x30", "xx ???? xxx"); dwFirstUserMsg = * (DWORD *) (* (DWORD *) (dwFirstUserMsg + 0x2)); } Return (CUserMessageHook *) dwFirstUserMsg; }
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)