Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

[KTUT] [C++,little ASM/RE] Hookujemy


Rekomendowane odpowiedzi

Opublikowano

Wyjaśnimy sobie co to jest hook

Mamy funkcję abc(int,int) która jest wykonywana w jakimś momencie programu, my tworząc hooka już na samym początku (można również potem) kodu skaczemy do naszej robiąc co nam się podoba wraz z możliwością powrotu w poprzednią funkcję.

Ale po co to komu

Silnik graficzny rysuje sobie "wszystko" co klatkę. Żeby osiągnąć WH, menu czy co wam się tam podoba musimy z(s?)hookować funkcję podsumowującą rysowanie i przed zakończeniem wrzucić swoje dane. Przykładów może być sporo, ale zapewne jak już tu trafiłeś to masz jakiś na myśli :)

Co zrobimy

Tutaj przydadzą się podstawy ASM'a i znajomości opcode'ów (które można znaleźć w sieci lub zapytać o nie swojego mistrza (TAK TO O TOBIE MIRAS <3)), a więc wyobraźmy sobie przykładową funkcję:
push eax
mov eax, 123h
pop eax
tak tak "nie robi ona nic", ale to tylko przykład teraz weźmy jego opcody
push eax || 50
mov eax, 12345678h || B8 78 56 34 12
pop eax || 58
W skrócie są to "numerki instrukcji" oraz dane podane w bajtach.
Przykładowo my chcemy skoczyć teraz do naszej funkcji (utworzyć hooka) więc musimy gdzieś tu wstrzyknąć E8 + adres. E8 - jest to skok (call 12345678h) w dane miejsce czyli do naszego hooka wraz z powrotem (ret). Musimy więc podmienić 5 bajtów (E8 < 1 bajt, adres < 4 bajty [xx xx xx xx]) Więc co by tu zrobić?
push eax || 50 < tutaj mamy jeden wolny
mov eax, 12345678h || B8 78 56 34 12 < tutaj mamy 5 wolnych, razem 6, ale nie możemy sobie zostawić jednego bajta luzem hmm..
pop eax || 58
Musimy spamiętać teraz opcody jakie mamy aby zrobić miejsce na 5 więc my wywalamy push eax oraz mov eax, 12345678h i na koniec dajemy jeden opcode 90 czyli NOP (instrukcja która "robi nic") i zostaje nam
call 12345678h
nop
pop eax

W opcode przed:
50 B8 78 56 34 12 58
po:
E8 78 56 34 12 90 58
Następnie w naszej funkcji musimy przed powrotem wykonać te "zaległe" instrukcje czyli
push eax
mov eax, 12345678h

Jak to wszystko zrobimy zrobimy

- musimy znać adres funkcji (jak go otrzymać: debuger, get address (google)) i ile musimy zapisać bajtów
- pobieramy sobie aktualne bajty do tabeli i nadpisujemy je callem (również można zrobić to E9 czyli jump'em, ale my zajmiemy się E8, ponieważ ma "wbudowany powrót")
- na końcu naszego hooka wykonujemy "zaległe" instrukcje i gotowe !

Praktyka

1. Program do testowania:
2Y8xn.png
Podajemy w nim 2 liczby, a następnie są one wypisywane, zadaniem naszego hooka będzie wypisanie tych wartości w odwróconej kolejności
2. Dowiadujemy się gdzie co jest w debugerze:

Od siebie polecam OllyDbg i to na nim będę działać
1. Uruchamiam program do testowania w ollym i działam

2. Szukam skoku do naszej funkcji
2Y8Sj.png

3. Analizuję funkcję
2Y8Mb.png

012D13A0 > 55               PUSH EBP
012D13A1   8BEC             MOV EBP,ESP
012D13A3   81EC C0000000    SUB ESP,0C0
012D13A9   53               PUSH EBX
012D13AA   56               PUSH ESI
012D13AB   57               PUSH EDI
012D13AC   8DBD 40FFFFFF    LEA EDI,DWORD PTR SS:[EBP-C0]
012D13B2   B9 30000000      MOV ECX,30
012D13B7   B8 CCCCCCCC      MOV EAX,CCCCCCCC
012D13BC   F3:AB            REP STOS DWORD PTR ES:[EDI]
012D13BE   8BF4             MOV ESI,ESP
012D13C0   8B45 0C          MOV EAX,DWORD PTR SS:[EBP+C]
012D13C3   50               PUSH EAX
012D13C4   8B4D 08          MOV ECX,DWORD PTR SS:[EBP+8]
012D13C7   51               PUSH ECX
012D13C8   68 3C572D01      PUSH OFFSET Hook_App.??_C@_0BA@NJLPAGBJ@>; ASCII "Numbers: %d %d
"
012D13CD   FF15 B8822D01    CALL DWORD PTR DS:[<&MSVCR100D.printf>]  ; MSVCR100.printf
012D13D3   83C4 0C          ADD ESP,0C
012D13D6   3BF4             CMP ESI,ESP
012D13D8   E8 59FDFFFF      CALL Hook_App.012D1136
012D13DD   5F               POP EDI
012D13DE   5E               POP ESI
012D13DF   5B               POP EBX
012D13E0   81C4 C0000000    ADD ESP,0C0
012D13E6   3BEC             CMP EBP,ESP
012D13E8   E8 49FDFFFF      CALL Hook_App.012D1136
012D13ED   8BE5             MOV ESP,EBP
012D13EF   5D               POP EBP
012D13F0   C3               RETN
4. Jak widzimy początek naszej funkcji prezentuje się następująco:
012D13A0 > 55               PUSH EBP
012D13A1   8BEC             MOV EBP,ESP
012D13A3   81EC C0000000    SUB ESP,0C0
Jest potrzebne 5 bajtów więc musimy niestety wywalić to wszystko, a resztę zastąpić nop'ami
Po zamianie początek kodu funkcji będzie prezentować się następująco:
CALL 12345678h
NOP
NOP
NOP
NOP


3. Tworzymy DLL która utworzy hooka

1. Tworzymy podstawowy szkielet DLL
2Y97g.png

2. Jak podmieniamy bajty kodu?
2YckZ.png
Wyjaśnijmy sobie co ta funkcja po kolei robi..
- zezwala nam na dostęp do kawałka kodu
- ustawia pierwszy bajt na E8 (call)
- ustawia kolejne 4 bajty na adres skoku
- ustawia resztę bajtów (u nas 4) na 90 (nop)
- zamyka dostęp

3. Dobrze mamy adres funkcji, mamy funkcję hookującą (tak zwany detour), ale co z naszym hookiem?
Gdybyśmy utworzyli zwykłego

void hook() {
}
Nasz kod wyglądał by tak
2Y9iB.png
No dobrze i co w tym złego? A no to, że mogło by to popsuć aktualny stos podczas działania hookowanej funkcji.
Dlatego tworzymy funkcję następująco
2Y9m5.png
__asm ret wykonuje nam instrukcję asm'a ret czyli wraca 5 bajtów za callem czyli na nasze nopy i przechodzi dalej

4. Podmieńmy sobie więc nasz cel
2Ycmo.png

5. Dobrze ale co teraz z "zaległymi" instrukcjami?
Wrzucamy je przed powrotem czyli
2Y9C8.png

6. Mamy skok, mamy powrót, wszystko jest ok, ale nasz hook nie robi nic!
Zacznijmy od tego czym jest rejestr ESP - wskaźnikiem na "aktualny" element na stosie
My więc musimy zaraz na początku naszej funkcji pobrać 2 ostatnie elementy ze stosu czyli 2 argumenty naszej funkcji
2YdTR.png
(już nie mamy call'a tylko jmp i wracamy również jmp to lekcja dla was nauczyć się dlaczego tak, a dlaczego tak :) )



Teraz pozostało tylko skompilować dll, wstrzyknąć ją do procesu i..
Coś jest nie halo! Przeróbmy sobie nasz testowy programik, żeby wypisywał nam adres funkcji do zhookowania przy starcie, ponieważ może on się zmieniać :)
2YdVc.jpg

Na koniec:
- macie pierwszy (przynajmniej ja nie mogłem znaleźć) w polsce poradnik o hookowaniu w sumie nie 0_O
- zakaz jakich kolwiek kopii
- kodu gotowego nie będzie - przepisywać i uczyć się !
- jeśli wyskakują wam jakieś errory to znaczy, że musicie to naprawić, jest pewna pułapka ciekawe czy ktoś na nią wpadnie hihihi

Pozdrawiam

/ GA-970A-UD3 / FX-6300 / Sapphire Xtreme 5830 / OCZ ZS 550W / Brutus M23 /

| MPC Coders Team | MPC Gold Member | C#, C++, PHP, (N)ASM, AutoIT, Python, Java |

Opublikowano

Odczep się ode mnie co ;x

mirasy za głupie na takie rzeczy o co tu chodzi

kaka_karrotcake_by_ask_bigmac-d5pm09i.jp

PS. Nie chcę tej plakietki kodersa, zabierzcie ją

207663_130456380451798_472220013_n.png

 

PS. To pisałem kodersom, cobyście mieli a co

 

 

Na to jest kilka sposobów w zależności od języka i rodzaju (właściwie konwencji) funkcji.

Do hookowania przydaje się biblioteka detours (pierwszy lepszy tut wszystko wyjaśnia).

 

Najpopularniejszą metodą haczenia to jmp na początku funkcji do naszej.

W praktyce wygląda to mniej więcej tak:

 

Dsiasm jakiejś funkcji:

funkcja:
push ebp ;55
mov ebp, esp ;8B EC
sub esp, 666 ;81 EC 66060000
...
Do przekierowania skorzystamy z instrukcji jmp (5 bajtów).
funckja:
jmp nasz_detour ;E9 DEADBEEF
nop ;90
nop ;90
nop ;90
nop ;90
Zanim jednak nadpiszemy prolog funkcji należy gdzieś oryginał zapisać.
LPVOID func_next = malloc(9 + 5);
memcpy(func_next, funckja, 9);
9 w tym przypadku to suma wielkości nadpisanych instrukcji (push ebp - 1, mov ebp, esp - 2, sub esp, 666 - 6 <- 1 + 2 + 6 = 9).

5 to dodatkowe bajty na potrzebę powrotu (jmp) z danego miejsca do kontynuacji (pierwszej instrukcji za nadpisanymi w hookowanej funkcji).

 

Następny krok to ustawienie jmpów. Instrukcja ta wykonuje skok o podaną deltę. Możemy sobie zapisać strukturę jmpa:

#pragma pack(1)
struct tJmp
{
BYTE bOpcode;
int iDelta;
};
Mając strukturę można zabrać się do dzieła (byle pamiętać by zdjąć wszelkie zabezpieczenia z modyfikowanego kawałka pamięci, zwykle kod ma prawa tylko do odczytu i wykonania):
tJmp *j = (tJmp*)funkcja;

j->bOpcode = 0xE9;
j->iDelta = (int)nasz_detour - (int)funkcja - sizeof(tJmp);
Na początku ustawiamy wskaźnik dla struktury tJmp na miejsce, gdzie ma się znaleźć instrukcja jmp. W tym przypadku na początku hookowanej funkcji coby przekierować ją do naszej (nasz_detour).

Deltę liczymy w sposób następujący: miejsce docelowe - adres instrukcji jmp - rozmiar instrukcji jmp.

 

To samo musimy wykonać dla skopiowanej części kodu by móc kontynuować działanie funkcji:

j = (tJmp*)((int)func_next + 9);

j->bOpcode = 0xE9;
j->iDelta = ((int)funkcja + 9) - (int)j - sizeof(tJmp);
Najgorsze za nami, funkcja przekierowana! Teraz czas wskazać kompilatorowi jakiego rodzaju ona jest.

Załóżmy, że nasza funkcja posiada konwencję stdcall i przyjmuje dwa argumenty- int i double oraz zwraca wartość char *. Zadeklarujmy więc wskaźnik:

char * (__stdcall *func_next)(int, double);
Teraz czas na nasz detour:
char * __stdcall nasz_detour(int a, double 
{
//instrukcje cokolwiek ma on robić
return func_next(a, ; //kontynuuj działanie funkcji
}
Podsumowując sklejmy wszystko do kupy:
#pragma pack(1)
struct tJmp
{
BYTE bOpcode;
int iDelta;
};

LPVOID ProstyHook(LPVOID origf, LPVOID hookf, int copylen)
{
tJmp *j;

LPVOID newf = malloc(copylen + 5); //alokujemy pamięć
memcpy(newf, origf, copylen); //kopiujemy instrukcje, które zostaną nadpisane

//teraz należy zdjąć protekcje z modyfikowanej pamięci
//dla windy:
DWORD dwOld;
if (VirtualProtect(origf, copylen, PAGE_EXECUTE_READWRITE, &dwOld))
{
j = (tJmp*)origf;
j->bOpcode = 0xE9;
j->iDelta = (int)hookf - (int)origf - sizeof(tJmp);
} else
return NULL;

//ustawiamy powrót do funkcji
j = (tJmp*)((int)newf + copylen);
j->bOpcode = 0xE9;
j->iDelta = ((int)origf + copylen) - (int)j - sizeof(tJmp);

//zwracamy wskaźnik hooka
return newf;
}
Jeszcze tylko hooki:
#define funckja 0x0ADD2E55

char *(__stdcall func_next)(int, double);

char * __stdcall nasz_detour(int a, double 
{
cout << a << " " << B << endl;
return func_next(a, ;
}

main()
{
//zakładamy hooka
func_next = (char*(__stdcall*)(int, double))ProstyHook((LPVOID)funkcja, (LPVOID)nasz_detour, 9);
}
Powyższy przykład ma za zadanie zobrazować w jaki sposób działa hooking. Biblioteka detours dla C++ posiada disasm więc potrafi sobie określić rozmiar instrukcji do skopiowania = jest wygodniejsza.

 

 

YOU MUST DIE

- Ganon, Koridai

Opublikowano

przecież to zaszczyt być w moim poradniku, a tu jeszcze problemy ma -.-

532399_452315051495153_1635392716_n.jpg

@miraś

ja doskonale znam detoursy, ale chciałem pokazać to od strony technicznej, a nie jedna funkcja i tyle

kaka_karrotcake_by_ask_bigmac-d5pm09i.jp

/ GA-970A-UD3 / FX-6300 / Sapphire Xtreme 5830 / OCZ ZS 550W / Brutus M23 /

| MPC Coders Team | MPC Gold Member | C#, C++, PHP, (N)ASM, AutoIT, Python, Java |

Opublikowano

- kodu gotowego nie będzie - przepisywać i uczyć się !

/ GA-970A-UD3 / FX-6300 / Sapphire Xtreme 5830 / OCZ ZS 550W / Brutus M23 /

| MPC Coders Team | MPC Gold Member | C#, C++, PHP, (N)ASM, AutoIT, Python, Java |

Opublikowano

kodu nie bedzie, ale jednak bedzie jak sobie przepiszesz z ssa, ja jebe, skoro ktos tu przyszedl cos wie o programowaniu, i na chuj ma przepisywac? w chuj bledow masz typu jakich kolwiek, no i jak dalesz wykrzynik, to nie daje sie spacji przed nim ...

Opublikowano

Przed zwyklym jmp patchem praktycznie kazda gra z antycheatem jest zabezpieczona. Wyjatkiem jest lekko zmieniony jmp patch, czyli tzw. mid-func hooking. Z tego co zauwazylem duzo bezpieczniejszy i mniej wykrywalny jest IAT/EAT hook. Poradnik nie pierwszy, bo o hookowaniu tez pisalem, poza tym jesli ktos zna asma to poradzi sobie z poradnikami w jezyku ang. ktorych jest od groma w necie i sa troche lepiej opisane. Pomysl moze i fajny, ale wykonanie srednie.

Opublikowano

No wreszcie konkretny polski poradnik wyjaśniający wszystko, dzięki wielkie bo niełatwo takie coś znaleźć, masz wygraną w kieszeni :).

Wszystkie poradniki w "O mnie" i na moim profilu YouTube.


51dd70965ae71.png


!!!HIT!!! -- Pełno klientów na DT nawet na najstarszym kompie bez zamuły!


!!!HIT!!! -- Nowa modyfikacja do Metina FastKill


World of Metin2


Opublikowano

Co do reszty:

- PRZEPISUJĄC UCZYSZ SIĘ CZEGOŚ ! Czy wy myślicie (a przynajmniej parę osó B),że piszę to po to, żeby na końcu dać gotowy kod i ktoś typu wy wejdzie skopiuje i pokaże kolegom jaki jest pro?

- tak tak poradnik jest zły przez to, że popełniłem parę drobnych błędów...

Co do drugiej reszty:

- Dzięki :)

Co do krycho:

- nie każda gra jest zabezpieczona przed tym to po 1, a po 2 prawie żadna nie jest zabezpieczona przed prostym bajerkiem typu

mov eax, 12345678h
jmp eax
: P

/ GA-970A-UD3 / FX-6300 / Sapphire Xtreme 5830 / OCZ ZS 550W / Brutus M23 /

| MPC Coders Team | MPC Gold Member | C#, C++, PHP, (N)ASM, AutoIT, Python, Java |

Opublikowano

Antycheat zazwyczaj sprawdza pierwsze 5 bajtow funkcji czy zostaly zmienione. Tutaj nie pomoze zadna sztuczka, bo musza byc identyczne. Jedynie pomoze hookowanie gdzies dalej, gdzie to sprawdzanie sie nie odbywa, bo wiadomo ze nie bedzie na biezaco sprawdzana pamiec calego procesu, bo byloby to niezbyt wydajne. Takie hooki sa raczej ostatecznoscia jesli iat/eat nie dzialaja. Te sa latwiejsze w uzyciu i czytelniejsze.

Opublikowano

Jeśli nie umie C/C++ to ma się w ogóle nie brać za ten poradnik, anie, że dostanie gotowca : OOOO

/ GA-970A-UD3 / FX-6300 / Sapphire Xtreme 5830 / OCZ ZS 550W / Brutus M23 /

| MPC Coders Team | MPC Gold Member | C#, C++, PHP, (N)ASM, AutoIT, Python, Java |

Opublikowano

to skoro ma umiec C to na chuj kazujesz przepisywac program typu hello world z obrazka lol? a tak wgl, to adresy beda rozne, jesli napisze cos innego, wiec chuja chyba skopiujesz, cos ci sie chlopczyku chyba pomieszalo xD

Opublikowano

"- PRZEPISUJĄC UCZYSZ SIĘ CZEGOŚ ! Czy wy myślicie (a przynajmniej parę osó B),że piszę to po to, żeby na końcu dać gotowy kod i ktoś typu wy wejdzie skopiuje i pokaże kolegom jaki jest pro?"

 

No tak, bo jak przepisze to już moze mówić ze jest pro...

 

Jeżeli chcem sie czegos nauczyc przepisujac to sobie przepisze, a jak nie chce to tego nie zrobie, dlaczego decydujesz za mnie ?

Może ten kod jest tak prosty że chuja sie z tego naucze a najem sie nerwów i porobię literówki przepisując.

Pisze boty do gier WWW na zlecenie.

Opublikowano

Nie jestem za gotowcami i sam nie kopiowałem nic z tego poradnika z żadnych stron ani nic po prostu uważam, że wtedy się nauczysz jak przepiszesz, nie pasuje możesz nie przepisywać, krótko

/ GA-970A-UD3 / FX-6300 / Sapphire Xtreme 5830 / OCZ ZS 550W / Brutus M23 /

| MPC Coders Team | MPC Gold Member | C#, C++, PHP, (N)ASM, AutoIT, Python, Java |

Opublikowano

Proszę pokaż mi jaka osoba potrafi pisać hooki po 20 minutach kursu C++? Kończę dyskusję na ten temat.

/ GA-970A-UD3 / FX-6300 / Sapphire Xtreme 5830 / OCZ ZS 550W / Brutus M23 /

| MPC Coders Team | MPC Gold Member | C#, C++, PHP, (N)ASM, AutoIT, Python, Java |

Opublikowano

Alse czy ty rozumiesz, że celem tego poradnika jest nauczenie się czym są najczęściej hooki i jak je tworzyć? : O proszę nie wypowiadaj sięjużw tym temacie..

/ GA-970A-UD3 / FX-6300 / Sapphire Xtreme 5830 / OCZ ZS 550W / Brutus M23 /

| MPC Coders Team | MPC Gold Member | C#, C++, PHP, (N)ASM, AutoIT, Python, Java |

Opublikowano

Ja się uczyłem kilka dni c++ i dałem sobie spokój.. mi ciężko cokolwiek wchodzi, ja myślę naraz o wielu sprawach ciężko jest mi się skupić na jednej rzeczy, więc dałem sobie spokój, może kiedyś powrócę jak będzie perfect angielski.

Opublikowano

Ja się uczyłem kilka dni c++ i dałem sobie spokój.. mi ciężko cokolwiek wchodzi, ja myślę naraz o wielu sprawach ciężko jest mi się skupić na jednej rzeczy, więc dałem sobie spokój, może kiedyś powrócę jak będzie perfect angielski.

 

tak bywa jak jest sie młodym po prostu twój mózg jest jeszcze niedorozwinięty przyjdzie z wiekiem pozdro ^^

Pisze boty do gier WWW na zlecenie.

Opublikowano

Jak widać poziom niektórych zwierząt jest poniżej zera, bo przecież ludźmi ich nie można nazwać. smutne

Opublikowano

No to tera se to przepisze na Pythona :D

btw. Szefie co oznacza ktut? (kkk)

Wiadro Bluba Rura Blant

 

(̅__(̲̲̲̲̲̅̅̅̅̅̅(̅_̅_̲̅м̲̅a̲̅я̲̅i̲̅h̲̅u̲̅a̲̅n̲̅ a̲̅ ̅_̅_̅((()ڪ

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...