Como Runescape captura os bots e por que ela não me pegou



Automatizar as ações do jogador sempre foi um grande problema em MMORPGs como World of Warcraft e Runescape . Esse tipo de hack de jogos é muito diferente dos cheats tradicionais, por exemplo, em shooters.



Em um fim de semana, decidi dar uma olhada nos sistemas de detecção que a Jagex usa para evitar que o Runescape automatize as ações do jogador.



Botanicultura



Nos últimos meses, a conta tem funcionado sem sch0u



parar no servidor world 67, realizando tarefas monótonas, como matar mobs e coletar recursos. À primeira vista, essa conta se parece com qualquer outro jogador, mas há uma diferença importante: é um bot .





Lancei este bot em outubro para testar os recursos do sistema de reconhecimento de bots. Depois de tentar encontrar informações sobre como a Jagex luta contra bots, só encontrei vídeos de bots pagos, cujos desenvolvedores se gabavam de que seus sistemas de movimento do mouse eram indistinguíveis das ações humanas.



Portanto, a única coisa que consegui entender foi a importância dos movimentos do mouse , mas será mesmo assim?



Heurística!



Para confirmar essa teoria, comecei examinando o cliente Runescape e quase imediatamente notei uma variável global hhk



sendo definida logo após o lançamento.



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





Este código instala um interceptor de baixo nível no mouse que é conectado à cadeia de interceptores do sistema . Isso permite que os aplicativos do Windows interceptem todos os eventos do mouse, mesmo se eles não estiverem associados a um aplicativo específico. Interceptadores de baixo nível (ganchos) são frequentemente usados ​​por keyloggers , mas também podem ser usados ​​para fins pacíficos, por exemplo, em heurísticas, como o interceptor de mouse mencionado anteriormente.



Na verdade, o manipulador do mouse do Runescape é bastante simples (o pseudocódigo foi ajustado para a beleza manualmente):



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;
  }
}
      
      





para reduzir a carga no link, essas funções rs::heuristics::log_*



usam algoritmos simples para pular dados de eventos que se assemelham a eventos registrados anteriormente.



Posteriormente, esses dados de evento são analisados ​​por uma função rs::heuristics::process



que é chamada de cada quadro do loop de renderização principal.



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);
}
      
      





Longe do teclado?



Durante o processo de engenharia reversa, tentei descobrir a importância de cada função que aprendi, geralmente criando ganchos ou patches para essas funções. Normalmente, você pode saber se um recurso é relevante tornando-o inútil e monitorando o estado do software. Essa metodologia de pesquisa levou a uma observação interessante.



Tendo proibido o jogo de chamar a função rs::heuristics::process



, a princípio não notei nada, mas depois de exatamente cinco minutos o servidor me desconectou. Obviamente, o Runescape determina a inatividade do jogador apenas pelos dados heurísticos transmitidos pelo cliente ao servidor, mesmo que você possa jogar normalmente. Isso levantou uma nova questão: se o servidor pensa que não estou jogando, ele pensa que estou jogando como um bot? ...



Depois disso, passei mais alguns dias fazendo engenharia reversa da camada de rede do jogo, para que meu bot agora possa fazer quase tudo usando apenas pacotes de rede .



Para validar minha teoria, me preocupei o dia todo, sete dias por semana, sem nem mesmo mover o mouse. Tendo passado milhares de horas assim, posso dizer com segurança que ou o sistema de detecção de bots usa apenas os dados de eventos heurísticos enviados ao servidor pelo cliente, ou só funciona quando o jogador não está "afk". Qualquer jogador que conseguir jogar sem mover o cursor deve ser banido imediatamente, ou seja, os desenvolvedores devem ficar atentos a esta falha.






All Articles