Wie Runescape die Bots fängt und warum sie mich nicht gefangen hat



Die Automatisierung von Spieleraktionen war in MMORPGs wie World of Warcraft und Runescape schon immer ein großes Problem . Diese Art des Hackens von Spielen unterscheidet sich stark von herkömmlichen Cheats, zum Beispiel bei Schützen.



Eines Wochenendes habe ich beschlossen, mir die Erkennungssysteme anzusehen, mit denen Jagex Runescape daran hindert, Spieleraktionen zu automatisieren.



Botanik



In den letzten Monaten hat das Konto sch0u



auf dem World 67-Server rund um die Uhr gespielt und monotone Aufgaben wie das Töten von Mobs und das Sammeln von Ressourcen ausgeführt. Auf den ersten Blick sieht dieses Konto wie jeder andere Spieler aus, aber es gibt einen wichtigen Unterschied: Es ist ein Bot .





Ich habe diesen Bot bereits im Oktober gestartet, um die Funktionen des Bot-Erkennungssystems zu testen. Nachdem ich versucht hatte, Informationen darüber zu finden, wie Jagex gegen Bot-Bots kämpft, fand ich nur Videos von bezahlten Bots, deren Entwickler sich rühmten, dass ihre Mausbewegungssysteme nicht von menschlichen Handlungen zu unterscheiden waren.



Das einzige, was ich verstehen konnte, war die Bedeutung von Mausbewegungen , aber ist das wirklich so?



Heuristik!



Um diese Theorie zu bestätigen, untersuchte ich zunächst den Runescape-Client und bemerkte fast sofort, hhk



dass kurz nach dem Start eine globale Variable festgelegt wurde.



const auto module_handle = GetModuleHandleA(0);
hhk = SetWindowsHookExA(WH_MOUSE_LL, rs::mouse_hook_handler, module_handle, 0);
      
      





Dieser Code installiert einen Low-Level-Interceptor auf der Maus , der an die System- Interceptor-Kette angeschlossen ist . Auf diese Weise können Windows-Anwendungen alle Mausereignisse abfangen, auch wenn sie keiner bestimmten Anwendung zugeordnet sind. Low-Level-Interceptors (Hooks) werden häufig von Keyloggern verwendet , können aber auch für friedliche Zwecke verwendet werden, beispielsweise in Heuristiken wie dem oben genannten Maus-Interceptor.



Tatsächlich ist der Maushandler von Runescape ziemlich einfach (der Pseudocode wurde von Hand auf Schönheit optimiert):



LRESULT __fastcall rs::mouse_hook_handler(int code, WPARAM wParam, LPARAM lParam)
{
  if ( rs::client::singleton )
  {
      // Call the internal logging handler
      rs::mouse_hook_handler_internal(rs::client::singleton->window_ctx, wParam, lParam);
  }
  // Pass the information to the next hook on the system
  return CallNextHookEx(hhk, code, wParam, lParam);
}
      
      





void __fastcall rs::mouse_hook_handler_internal(rs::window_ctx *window_ctx, __int64 wparam, _DWORD *lparam)
{
  // If the mouse event happens outside of the Runescape window, don't log it.
  if (!window_ctx->event_inside_of_window(lparam))
  {
    return;
  }

  switch (wparam)
  {
    case WM_MOUSEMOVE:
      rs::heuristics::log_movement(lparam);
      break;
    
    case WM_LBUTTONDOWN:
    case WM_LBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
    case WM_MBUTTONDBLCLK:
      rs::heuristics::log_button(lparam);
      break;
  }
}
      
      





Um die Belastung der Verbindung zu verringern, verwenden diese Funktionen rs::heuristics::log_*



einfache Algorithmen, um Ereignisdaten zu überspringen, die zuvor aufgezeichneten Ereignissen ähneln.



Später werden diese Ereignisdaten von einer Funktion analysiert rs::heuristics::process



, die jeden Frame der Hauptrenderschleife aufruft.



void __fastcall rs::heuristics::process(rs::heuristic_engine *heuristic_engine)
{
  // Don't process any data if the player is not in a world
  auto client = heuristic_engine->client;
  if (client->state != STATE_IN_GAME)
  {
    return;
  }

  // Make sure the connection object is properly initialised
  auto connection = client->network->connection;
  if (!connection || connection->server->mode != SERVER_INITIALISED)
  {
    return;
  }

  // The following functions parse and pack the event data, and is later sent
  // by a different component related to networking that has a queue system for
  // packets.

  // Process data gathered by internal handlers
  rs::heuristics::process_source(&heuristic_engine->event_client_source);

  // Process data gathered by the low level mouse hook
  rs::heuristics::process_source(&heuristic_engine->event_hook_source);
}
      
      





Nicht am Computer?



Während des Reverse Engineering-Prozesses habe ich versucht, die Bedeutung jeder erlernten Funktion für mich herauszufinden, indem ich normalerweise Hooks oder Patches für diese Funktionen erstellt habe. Normalerweise können Sie feststellen, ob eine Funktion relevant ist, indem Sie sie unbrauchbar machen und den Status der Software überwachen. Diese Forschungsmethode führte zu einer interessanten Beobachtung.



Nachdem ich dem Spiel verboten hatte, die Funktion aufzurufen rs::heuristics::process



, bemerkte ich zunächst nichts, aber nach genau fünf Minuten meldete mich der Server ab. Offensichtlich bestimmt Runescape die Inaktivität des Spielers ausschließlich anhand der Heuristikdaten, die vom Client an den Server übertragen werden, selbst wenn Sie ganz normal spielen können. Dies warf eine neue Frage auf: Wenn der Server denkt, dass ich nicht spiele, glaubt er dann, dass ich als Bot spiele? ...



Danach habe ich noch ein paar Tage damit verbracht, die Netzwerkschicht des Spiels zurückzuentwickeln, sodass mein Bot jetzt fast alles mit Netzwerkpaketen alleine tun kann .



Um meine Theorie zu bestätigen, habe ich mich sieben Tage die Woche rund um die Uhr darum gekümmert, ohne meine Maus zu bewegen. Nachdem ich Tausende von Stunden so verbracht habe, kann ich mit Sicherheit sagen, dass entweder das Bot-Erkennungssystem nur die Daten heuristischer Ereignisse verwendet, die vom Client an den Server gesendet wurden, oder nur funktioniert, wenn der Player nicht "afk" ist. Jeder Spieler, der es schafft, ohne den Cursor zu bewegen, sollte sofort gesperrt werden, dh Entwickler sollten auf diesen Fehler achten.






All Articles