Projektowanie stron WWW od podszewki

Artykuły na każdy temat

[C++] Hookowanie funkcji send() i recv()

Dodano 08.06.2012r. o 04:28
W poprzednim artykule wspomniałem, że ostatnimi czasy bawię się w DLL Injection i hookowanie funkcji. Niby nic nadzwyczajnego ale pomyślałem sobie, że zrobię kolejną myślodsiewnie. Można powiedzieć, że była to chwilowa zachcianka aby podejrzeć komunikacje pewnego programu, który wali dane w "plain/text". Jak zwykłe cel został osiągnięty. W międzyczasie miałem okazje przetestować Detours oraz EasyHook. Całkiem fajne narzędzia Smile Żeby nie przedłużać podaję źródła biblioteki do hookowania send() i recv():
Kod:
#include <winsock2.h>
#include <windows.h>
#include <iostream>

typedef INT (WINAPI *SendPtr)(SOCKET sock, CONST CHAR* buf, INT len, INT flags);
typedef INT (WINAPI *RecvPtr)(SOCKET sock, CHAR* buf, INT len, INT flags);

INT WINAPI OurSend (SOCKET sock, CONST CHAR* buf, INT len, INT flags);
INT WINAPI OurRecv (SOCKET sock, CHAR* buf, INT len, INT flags);

VOID *Detour(BYTE *source, CONST BYTE *destination, CONST INT length);

SendPtr RealSend;
RecvPtr RealRecv;
HANDLE Console;

BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
   if(reason == DLL_PROCESS_ATTACH)
   {
      // Dla okienkowych aplikacji i osób nie lubiących OutputDebugString(), można jeszcze dodać logowanie pakietów do pliku
      AllocConsole();
      Console = GetStdHandle(STD_OUTPUT_HANDLE);
      CHAR buffer[256];

      RealSend = (SendPtr)GetProcAddress(GetModuleHandle("ws2_32.dll"), "send");
      RealRecv = (RecvPtr)GetProcAddress(GetModuleHandle("ws2_32.dll"), "recv");

      sprintf(buffer, "Adres send() w aplikacji = 0x%x\n", RealSend);
      WriteConsole(Console, buffer, strlen(buffer), NULL, NULL);
      sprintf(buffer, "Adres recv() w aplikacji = 0x%x\n", RealRecv);
      WriteConsole(Console, buffer, strlen(buffer), NULL, NULL);

      RealSend = (SendPtr)Detour((BYTE*)RealSend, (BYTE*)&OurSend, 5);
      RealRecv = (RecvPtr)Detour((BYTE*)RealRecv, (BYTE*)&OurRecv, 5);

      sprintf(buffer, "Adres send() w bibliotece = 0x%x\n", RealSend);
      WriteConsole(Console, buffer, strlen(buffer), NULL, NULL);
      sprintf(buffer, "Adres recv() w bibliotece = 0x%x\n", RealRecv);
      WriteConsole(Console, buffer, strlen(buffer), NULL, NULL);
   }
   else if(reason == DLL_PROCESS_DETACH)
   {
      CloseHandle(Console);
      FreeConsole();
   }

   return TRUE;
}

VOID *Detour(BYTE *source, CONST BYTE *destination, CONST INT length)
{
   DWORD back;
   BYTE *jmp = (BYTE*)malloc(length + 5);

   VirtualProtect(source, length, PAGE_READWRITE, &back);
   memcpy(jmp, source, length);
   jmp += length;

   jmp[0] = 0xE9;
   *(DWORD*)(jmp + 1) = (DWORD)(source + length - jmp) - 5;

   source[0] = 0xE9;
   *(DWORD*)(source + 1) = (DWORD)(destination - source) - 5;

   VirtualProtect(source, length, back, &back);

   return (jmp - length);
}

INT WINAPI OurSend(SOCKET sock, CONST CHAR* buf, INT len, INT flags)
{
   CHAR buffer[256];

   sprintf(buffer, "SEND -> %s\n", buf);
   WriteConsole(Console, buffer, strlen(buffer), NULL, NULL);
   // OutputDebugString(buffer);

   return RealSend(sock, buf, len, flags);
}

INT WINAPI OurRecv(SOCKET sock, CHAR* buf, INT len, INT flags)
{
   CHAR buffer[256];

   sprintf(buffer, "RECV -> %s\n", buf);
   WriteConsole(Console, buffer, strlen(buffer), NULL, NULL);
   // OutputDebugString(buffer);

   return RealRecv(sock, buf, len, flags);
}

Komentarze

Publikowane komentarze są prywatnymi opiniami użytkowników serwisu. Serwis nie ponosi odpowiedzialności za treść opinii. W trosce o zachowanie poziomu dyskusji wszystkie komentarze podlegają akceptacji przed ich publikacją dlatego proszę cierpliwie czekać aż komentarz zostanie opublikowany.

CapaciousCore

Dodano 26.09.2015r. o 16:44
@jedker2525 Proszę podać więcej szczegółów.

jedker2525

Dodano 21.12.2014r. o 10:06
Kod:
VOID *Detour(BYTE *source, CONST BYTE *destination, CONST INT length)

{
// ...
BYTE *jmp = (BYTE*)malloc(length + 5);
memcpy(jmp, source, length);
VirtualProtect(jmp, length, PAGE_EXECUTE_READWRITE, &back);
// ...
}
ochrona pamięci w systemie wywala program kiedy ten chce się wykonywać w miejscu gdzie nie powinien czyli "*jmp "

programer1234

Dodano 05.07.2012r. o 21:55
Na dobrą sprawę ja mam na komputerze zainstalowane 3 kompilatory... tfu, IDE. Głównie korzystam z C::B, ale tak jak napisałem większość nowości testuję w Devie.

Przeniosłem potem kod do C::B, i co? Po zmianie kilku flag przestało wywalać, i śmiga jak należy ;) W sumie nie wiem co jest przyczyną wywalania się pod Devem, ale jakoś zbytnio mnie to nie interesuje Razz

Wprawdzie problem już "rozwiązany", ale jeśli chcesz pogadać, to napisz na maila, a ja ci GG podam Smile

CapaciousCore

Dodano 05.07.2012r. o 21:25
@programer1234 szczerze mówiąc miałem na myśli jakieś ID na komunikator, bo via mail to se można Razz To prawda, że dbg od devcpp sam wymaga debugowania. Oh ironio losu Smile Jak chcesz korzystać z devcpp to proponuje Ci używać "nowszej wersji" tj. wxDev-C++.

Ogólnie ten kod powyżej i wszystko co pisze w C++ jest pisane pod Visual Studio 2k8 i jego kompilator ;)

programer1234

Dodano 05.07.2012r. o 17:59
Ja wiem, ale niektórzy nie chcą tego przyjąć do wiadomości. W sumie nie tylko na tamtym forum.
Z drugiej strony nie dziwię im się Smile

Generalnie wszystkie testowe projekty tworzę pod Dev-C++, a tam jak wiadomo Debugger nie istnieje. Potem będę przerzucał kody na C::B, i zobaczymy Smile

Jeśli chcesz, to pisz na maila, jako administrator na pewno go widzisz ;)

CapaciousCore

Dodano 05.07.2012r. o 17:31
@programer1234 oj tam w jakim hackowaniu. To hookowanie i nie tylko hackerzy wykorzystują takie techniki Razz Deklaracja funkcji jest prawidłowa? Sprawdzałeś pod dbg czy adres się zgadza? Trudno mi tak na sucho coś powiedzieć. Zostaw via PM na siebie namiar to może wieczorem się odezwę.

programer1234

Dodano 05.07.2012r. o 17:27
Taa, już widzę te odpowiedzi "nie pomagamy w hackowaniu"... Ale dobra, spróbuję sam rozwiązać problem Smile Coś jakby z tym wskaźnikiem na oryginalną funkcję było nie tak...

CapaciousCore

Dodano 05.07.2012r. o 17:25
@programer1234 szczerze mówiąc nie mam pomysłu, a dokładniej rzecz ujmując mój mózg nie funkcjonuje w dużych temperaturach (28,4°C w pokoju). Proponuję zadać to pytanie na tym forum. Jest tam masa specjalistów i myślę, że ktoś Ci pomoże.

programer1234

Dodano 05.07.2012r. o 17:17
@CapaciousCore:
Napisałem gwoli przestrogi, bo sam wpadłem w te sidła ;)

Tylko teraz mam mały problem, bo po użyciu SetWindowText (tą funkcję zhookowałem) tekst jest wypisywany na konsolę, a następnie właściwa aplikacja zawiesza się (wcześniej nie zwróciłem na to uwagi). Kod jest identyczny jak tutaj, z tym że pozamieniałem nazwy wskaźników na bardziej adekwatne do tej funkcji. Masz może pomysł gdzie może być błąd?

CapaciousCore

Dodano 05.07.2012r. o 17:00
@programer1234 oczywista oczywistość. Ma się rozumieć, że właśnie tak trzeba robić Razz

programer1234

Dodano 05.07.2012r. o 16:53
Świetny kod, co najważniejsze - działa Smile Wielkie dzięki Smile

Jeśli ktoś chciałby go używać do funkcji które w WinAPI mają wersje ANSI i UNICODE, niech pamięta o użyciu literek "A" lub "W", w przeciwnym razie funkcja GetProcAddress zawiedzie ;)

Dodaj komentarz

Zostaw komentarz jeżeli możesz! Nie bądź przysłowiowym botem! Nie bądź obojętny! Ciebie to nic nie kosztuje, a mi sprawi uśmiech na twarzy.
Zezwolono używać: BBCode
Zabroniono używać:
znaczników HTML

(Wymagany)

(Wymagany, niepublikowany)

(Nie wymagana)

Token:

Obrazek dla bota

(Przepisz tylko cyfry!)

(Wymagana)