• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak pisane są boty do gier

Object Storage Arubacloud
0 głosów
4,355 wizyt
pytanie zadane 1 czerwca 2017 w C i C++ przez jankustosz1 Nałogowiec (35,880 p.)
Witam.

Jak pisane są boty do gier? Nie mam tu na myśli prostych bocików ruszających myszką i pobierających pixele, tylko takie które "włamują" się do pamięci gry i pobierają różne informacje np. pozycja itp. Skąd wogóle twórcy takich botów wiedzą co gdzie i jak jest zapisane? Jak np. jest zrobiony taki bot który strzela w głowę przeciwnikom w CS GO?

3 odpowiedzi

+2 głosów
odpowiedź 1 czerwca 2017 przez Knayder Nałogowiec (37,640 p.)
wybrane 1 czerwca 2017 przez jankustosz1
 
Najlepsza

Interesowałem się tym tematem jakiś czasu temu. Z tej mojej zajawki wyniknął aimbot oraz triggerbot do gry Assault Cube - Czyli chyba najłatwiejszej do zcheatowania gry. Wszystko skupia się na pobieraniu wartości z ramu (Przynajmniej w przypadku assault cube).
Tutaj masz offsety i base addressy do tejże właśnie gry: https://www.unknowncheats.me/forum/other-fps-games/140127-assault-cube-some-offsets.html

Ale na czym to polega? Otóż, każda komórka w pamięci (Bajt) ma własny adres. Adres ten zapisywany jest w systemie szesnastkowym.

Base Address: To taki adres, który zawsze jest taki sam (Normalnie się zmienia po zrestartowaniu aplikacji). W przypadku Assault Cube jest to:  0x400000;

Offset: Wartość którą należy dodać do base addressu żeby dostać się do danej zmiennej zapisanej w ramie.
Żeby dostać się do klasy Player (Czyli klasy która ma w sobie wszystkie parametry gracza jak pozycja, amunicja, życie itp.) należy do Base Addressu dodać: 0x10F4F4. (Można powiedzieć że BasePlayerAddress = BaseAddress + OffsetPlayer. )

Potem to już czysta matematyka. Znając pozycje obu graczy (W Assault Cube w klasie Player jest pozycja głowy) wystarczy funkcją atan2() obliczyć kąt pod jakim ma patrzeć gracz, żeby celować na głowę przeciwnika.
Znając tą wartość zmieniamy ją w ramie (Albo symulujemy ruch myszki).

Dwie funkcje do odczytu i zapisu w ramie:
ReadProcessMemory oraz WriteProcessMemory 

Do tablicy przechowującej graczy też jest offset podany na tej stronie. :)

komentarz 1 czerwca 2017 przez Knayder Nałogowiec (37,640 p.)
Logicznym jest że nie do każdej gry znajdziesz base addressy i offsety w internecie.
Dobrym programem w który można ich szukać na własną rękę jest Cheat Engine.
komentarz 1 czerwca 2017 przez Knayder Nałogowiec (37,640 p.)
Oczywiście to co napisałem to nie jest jedyny statyczny sposób jak pisać cheaty.
Można wykorzystywać funkcję napisane przez programistów gry, zmieniać ich działanie (W przypadku Assault Cube, czyli gry Open Source, możesz też skompilować własną wersję gry i odpalić ja na multiplayer. Mam nadzieję że wiesz co oznacza własna wersja gry :D). Na 100% istnieje wiele więcej sposobów, o których najzwyczajniej w świecie nie wiem :D
komentarz 1 czerwca 2017 przez jankustosz1 Nałogowiec (35,880 p.)
3 pytania:

1) Co z adresami alokowanymi dynamicznie które się zmieniają po ponownym uruchomieniu aplikacji? Jest jakiś sposób?

2) Czy da się samemu jakoś dojść do tego że jest taka klasa jak Player, i jakie są metody i co robią, jak je wogóle wywoływać, znasz jakiś fajny kurs?

3) W takim CS dałoby się chyba za pomocą cheat engine zdobyć dane o własnej pozycji i wysokości, ale zdobycie już pozycji przeciwnika byłoby trudniejsze i pewnie by się zmieniał adres (dynamicznie alokowany) bo jest ich wielu. (żeby kogoś zastrzelić trzeba znać jego pozycję). Oprócz tego takie profesjonalne boty pewnie jeszcze sprawdzają czy nie ma pomiędzy nim a głową przeciwnika przeszkód, aby kula go walnęła. Skąd tacy profesjonaliści biorą te wszystkie adresy???
komentarz 1 czerwca 2017 przez Knayder Nałogowiec (37,640 p.)

1. Słuchaj, dynamiczne alokowanie odbywa się na wskaźniku:
int *tab = new int[10];
Co znaczy, że sam wskaźnik zawsze jest w tym samym miejscu (offset), a to na co wskazuje się zmienia. (Zmienna trzyma w sobie adres innej zmiennej).

2. No tak jak już mówiłem. Cheat enginem. Nie jestem jakimś specem w tej dziedzinie, ale z tego co sam się tym bawiłem to: Jest tam taka opcja, że od danego adresu pokazuje wartości w kolejnych bajtach. Można z tego wywnioskować co jest np. życiem, pozycją itp.
Załóżmy że mamy adres gracza: 0x000000.
Interesuje nas 300 bajtów.
Tworzymy klasę w swoim programie, który zajmuje właśnie tych 300 bajtów.

class Player{
    BYTE bytes[300];
}
//Teraz wystarczy wczytać dane z ramu:
int main(){
   ....
   Player player;
   ReadProcessMemory(handle, (void*)0x000000, &player, sizeof(player), NULL);
}

Po czymś takim, mamy zapisaną naszą własną wersję klasy Player.
Funkcją ReadprocessMemory wczytaliśmy dane z ramu. (300 bajtów).
Możliwe że oryginalna klasa Player miała więcej tych bajtów, ale skoro ich nie potrzebujemy, to nie musimy ich pobierać ;)

Tylko co nam po takiej klasie, ciężko byłoby wyjmować życie z 4 Bajtów, (zakładamy że życie zapisywane jest w typie int). Lepiej napisać tak klasę, żeby znajdowała się już tam ta zmienna.

Załóżmy że:
Adres gracza: 0x000000
Offset życia: 0x8
Rozmiar klasy player: 300 bajtów
 

class Player{
   BYTE _0x0[8];
   int health;
   BYTE _0xC[288]; //300 - (8+4);
}

 

3. Biorą te adresy różnymi programami. Np. właśnie Cheat Engine (nie wiem czy kiedys korzystałeś, ale ja jak byłem młodszy, to dodawałem sobie pieniądze w grach lokalnych xD). Wbrew pozorom, jest to bardzo potężne narzędzie.
Wybierasz program, np. CSGO. Wpisujesz pierwszą wartość np. 100 (Szukamy życia). Znajduje ci ileśset tysięcy pozycji z adresami w pamięci przechowującymi liczbę 100.
W grze zadajesz sobie trochę obrażeń. Potem znowu szukasz, tym razem program szuka tylko w tych, dla których wcześniejsza wartość wynosiła 100. Tak dochodzimy nawet do jednego adresu. To jest adres komórki z wartością życia. (Nie jest to base address. Szukanie ich jest bardziej skomplikowane, poszukaj w necie :D).
 

komentarz 1 czerwca 2017 przez Knayder Nałogowiec (37,640 p.)

Tutaj masz przykład klasy Player dla gry Assault Cube:
 

class Player
{
public:
	virtual void Function0(); //
	virtual ~Player(); //
	virtual void Function2(); //
	virtual void Function3(); //
	virtual void OnCollision(); //
	virtual void OnMoved(const Vec3 &dist); //
	virtual void Function6(); //
	virtual void Function7(); //
	virtual void Function8(); //
	virtual void Function9(); //
 
	Vec3 m_HeadPos; //0x0004 
	Vec3 m_Velocity; //0x0010 
	char _0x001C[24];
	Vec3 m_FootPos; //0x0034 
	float m_Yaw; //0x0040 
	float m_Pitch; //0x0044 
	float m_Roll; //0x0048 
	float m_PitchVel; //0x004C
	float m_MaxSpeed; //0x0050
	__int32 m_AirTime; //0x0054 
	float m_Radius; //0x0058 
	float m_Height; //0x005C 
	float m_NormalHeight; //0x0060 
	float m_HeightAboveHead; //0x0064 
	BYTE m_IsInWater; //0x0068 
	BYTE m_IsOnFloor; //0x0069 
	BYTE m_IsOnLadder; //0x006A 
	BYTE m_JumpNext; //0x006B 
	BYTE m_Crouching; //0x006C 
	BYTE m_AirCrouch; //0x006D 
	char _0x006E[1];
	BYTE m_CanCollide; //0x006F 
	BYTE m_IsNotInGame; //0x0070 
	BYTE m_Scoping; //0x0071 
	BYTE m_Shooting; //0x0072 
	char _0x0073[5];
	float m_LastJumpYPos; //0x0078 
	__int32 m_LastSplash; //0x007C 
	BYTE m_Move; //0x0080 
	BYTE m_Strafe; //0x0081 
	BYTE m_State; //0x0082 
	BYTE m_Type; //0x0083 
	char _0x0084[116];
	__int32 m_Health; //0x00F8 
	__int32 m_Armor; //0x00FC 
	__int32 m_Primary; //0x0100 
	char _0x0104[4];
	__int32 m_GunSelect; //0x0108 
	BYTE m_AkimboEquipped; //0x010C 
	char _0x010D[7];
	__int32 m_SecondaryAmmoInReserve; //0x0114 
	char _0x0118[16];
	__int32 m_PrimaryAmmoInReserve; //0x0128 
	char _0x012C[8];
	__int32 m_AkimboAmmoInReserve; //0x0134 
	char _0x0138[4];
	__int32 m_SecondaryAmmo; //0x013C 
	char _0x0140[16];
	__int32 m_PrimaryAmmo; //0x0150 
	char _0x0154[4];
	__int32 m_GrenadeAmmo; //0x0158 
	__int32 m_AkimboAmmo; //0x015C 
	__int32 m_MeleeDelayTime; //0x0160 
	__int32 m_SecondaryDelayTime; //0x0164 
	char _0x0168[16];
	__int32 m_PrimaryDelayTime; //0x0178 
	char _0x017C[4];
	__int32 m_GrenadeWaitingTime; //0x0180 
	__int32 m_AkimboWaitingTime; //0x0184 
	__int32 m_MeleeShotsFired; //0x0188 
	__int32 m_SecondaryShotsFired; //0x018C 
	char _0x0190[16];
	__int32 m_PrimaryShotsFired; //0x01A0 
	char _0x01A4[4];
	__int32 m_GrenadeShotsFired; //0x01A8 
	__int32 m_AkimboShotsFired; //0x01AC 
	char _0x01B0[44];
	__int32 m_Skin; //0x01DC 
	__int32 m_NextSkin; //0x01E0 
	__int32 m_ClientID; //0x01E4 
	__int32 m_LastUpdate; //0x01E8 
	__int32 m_Lag; //0x01EC 
	__int32 m_Ping; //0x01F0 
	DWORD m_IPaddress; //0x01F4 
	__int32 m_TimesRespawned; //0x01F8 
	__int32 m_Kills; //0x01FC 
	__int32 m_FlagScore; //0x0200 
	__int32 m_Deaths; //0x0204 
	__int32 m_Score; //0x0208 
	__int32 m_TeamKills; //0x020C 
	__int32 m_LastAction; //0x0210 
	__int32 m_LastMove; //0x0214 
	__int32 m_LastHurt; //0x0218 
	__int32 m_LastVoiceCom; //0x021C 
	__int32 m_ClientRole; //0x0220 
	BYTE m_IsShooting; //0x0224 
	char m_Name[260]; //0x0225 
	__int32 m_Team; //0x0329 
	__int32 m_Weaponchanging; //0x032D 
	__int32 m_NextWeapon; //0x0331 
	__int32 m_SpectateMode; //0x0335 
	__int32 m_SpectateCN; //0x0339 
	__int32 m_EarDamageMillis; //0x033D 
	__int32 m_RespawnOffset; //0x0341 
	char __0xbuf[7]; //0x0225 
	Weapon *m_Weapons[10]; //0x348
	//char _0x0345[4];
 
};//Size=0x0349

Kod wzięty z tej strony: https://www.unknowncheats.me/forum/1154594-post6.html

komentarz 1 czerwca 2017 przez jankustosz1 Nałogowiec (35,880 p.)
Dzięki wielkie.
0 głosów
odpowiedź 1 czerwca 2017 przez marcin99b Szeryf (82,180 p.)
Hmm, może sprawdzają dane w pamięci ram?
komentarz 1 czerwca 2017 przez piotrsz109 Stary wyjadacz (13,730 p.)
Na swój sposób nie. Ale ludzie kodzą boty naprawde zaawansowane lecz dokładnie nie wiem jak to działa. Nie potrzebują dokładnej lokalizacji gracza. Wystarczy proste drzewo zachowań.
komentarz 1 czerwca 2017 przez piotrsz109 Stary wyjadacz (13,730 p.)
Każdy obiekt ma swój tag. Gracz ma np.: Player, bot np.: BOT
komentarz 1 czerwca 2017 przez jankustosz1 Nałogowiec (35,880 p.)
To nie jest takie proste jak myślisz bo nie mogą sobie tak zwyczajnie pobrać pozycje gracza jak Ty byś to zrobił pisząc grę, muszą wiedzieć gdzie ta pozycja jest zapisana.
komentarz 1 czerwca 2017 przez piotrsz109 Stary wyjadacz (13,730 p.)
Mówię to na odpowiedź pytania jak rozponać bota gracza a jak bota gry.
komentarz 1 czerwca 2017 przez piotrsz109 Stary wyjadacz (13,730 p.)
Nie sądzę.
0 głosów
odpowiedź 1 czerwca 2017 przez piotrsz109 Stary wyjadacz (13,730 p.)
Jest wiele rozwiązań. Na przykład wykorzystują drzewo zachowań, sieci neuronowe. Strzelanie w głowę np.: w unity polega na pobieraniu "obrazów" z kamery bota i są one przetwarzane. To zależy od rodzaju gry.
komentarz 1 czerwca 2017 przez piotrsz109 Stary wyjadacz (13,730 p.)
Jeśli ma ci wbić z Silvera do Globala i chcesz zarobić warto popracować parę miesięcy
komentarz 1 czerwca 2017 przez jankustosz1 Nałogowiec (35,880 p.)
Mnie po prostu ciekawi jak takie coś działa i umieć takiego bota napisać. Te ostatnie posty co pisaliśmy to takie trochę gadanie o niczym. Zadam konkretniejsze pytania:

1)Skąd twórca bot miałby wiedzieć pod jakim adresem w procesie gry zapisana jest np. pozycja i jaki ma typ?

2) Czy może takie coś zrobić osoba która nie była programistą danej gry. (takie coś w sensie bot wykorzystujący punkt 1) Zwykłego przetwarzającego pixele to i ja zrobiłem.
komentarz 1 czerwca 2017 przez piotrsz109 Stary wyjadacz (13,730 p.)
1. Twórca ma dostęp do zmiennych, bo to kodzi robi se gety i sety itp.

2. Jeśli to jest gra 2D i pixelowa to tak. Do CS:GO nie dałbyś rady raczej chociaż gdybyś się postarał i poświęcił troche procka może by się udało
komentarz 1 czerwca 2017 przez jankustosz1 Nałogowiec (35,880 p.)

1) Mam na myśli twórce bota a nie twórce gry, twórca bota nie ma zwykłego dostępu do zmiennych z gry

2) Jeszcze raz napiszę pytanie bo chyba nie zrozumiałeś: 

Czy może takie coś zrobić osoba która nie była programistą danej gry. (takie coś w sensie bot wykorzystujący punkt 1)

"takie coś" w sensie pobieranie adresów zmiennych z gry w bocie, prościej nie umiem wytłumaczyć.

komentarz 1 czerwca 2017 przez piotrsz109 Stary wyjadacz (13,730 p.)
Raczej tak lecz musisz mieć dokładne grafiki aby mógł bot porównać obrazy lub kod rozpoznający obraz podobny do danego -> sieć neuronowa.

Pozycję mógłbyś namierzyć jeśli jest to gra rundowa to możesz po respawnie podstawić. Podobnie jak Cheat Engine

Podobne pytania

0 głosów
1 odpowiedź 439 wizyt
pytanie zadane 17 czerwca 2019 w Offtop przez mrbestdonuts Początkujący (260 p.)
+4 głosów
1 odpowiedź 688 wizyt
pytanie zadane 27 października 2017 w Inne języki przez prominepl Bywalec (2,440 p.)
0 głosów
3 odpowiedzi 228 wizyt
pytanie zadane 1 czerwca 2017 w PHP przez sapero Gaduła (4,100 p.)

92,580 zapytań

141,433 odpowiedzi

319,665 komentarzy

61,965 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...