O maior portal de MU Online do Brasil — desde 2003
Tutorial Avançado Cliente

Como configurar anti-tamper (proteção) do cliente de MU Online

Blinde o Main.exe do seu servidor de MU Online contra edição, injeção e memory hacks combinando checksum de integridade, anti-debug, verificação de módulos e um handshake assinado com o servidor.

GA Gabriel · Atualizado em 12 jul 2025 · ⏱ 24 min de leitura
Resposta rápida

Proteger o cliente de MU Online é uma corrida armamentista permanente. Do outro lado estão editores hexadecimais, injetores de DLL, trainers de memória e cheats de speed, wallhack e auto-combo que se aproveitam de um Main.exe desprotegido. O anti-tamper é o conjunto de defesas que dificulta editar o

Proteger o cliente de MU Online é uma corrida armamentista permanente. Do outro lado estão editores hexadecimais, injetores de DLL, trainers de memória e cheats de speed, wallhack e auto-combo que se aproveitam de um Main.exe desprotegido. O anti-tamper é o conjunto de defesas que dificulta editar o binário, anexar um debugger, injetar código e alterar valores em memória — e, tão importante quanto, permite que o servidor detecte quando o cliente não é confiável. Neste tutorial você vai montar essas camadas de forma prática: integridade por checksum, anti-debug, verificação de módulos carregados, proteção de memória e um handshake assinado com o servidor. Todos os valores concretos (offsets, portas, nomes de seção) aparecem como exemplo e variam por season/cliente.

Pré-requisitos

Antes de blindar qualquer coisa, você precisa de uma base funcional. Se ainda está montando o servidor, comece por como criar um servidor de MU Online e volte aqui quando o cliente já conectar normalmente. Blindar um cliente que ainda nem loga só multiplica variáveis quando algo quebrar.

RequisitoDetalhe (exemplo — varia por season/cliente)
Cliente funcionalMain.exe que conecta e loga sem proteção ainda
Backup do binárioCópia intocada Main_original.exe fora da pasta do cliente
Ferramentas de análiseHxD, CFF Explorer, x64dbg, Process Hacker
Launcher próprioExecutável que valida e inicia o cliente (ideal)
Acesso ao ConnectServerPara adicionar validação server-side
Ambiente de teste isoladoMáquina limpa, separada da de desenvolvimento

O item menos óbvio é o launcher próprio. Muita proteção fica melhor num componente que você controla totalmente e pode recompilar à vontade, em vez de tentar remendar o Main.exe que veio no pacote. O launcher verifica integridade, conversa com o servidor e só então dispara o cliente.

Modelo de ameaças: contra o que você está protegendo

Antes de escolher técnicas, defina o que o atacante quer fazer. Proteção genérica desperdiça CPU e gera falso positivo; proteção dirigida ao ataque real vale o esforço.

AtaqueVetor típicoDefesa principal
Editar IP/versão no binárioHxD, patcherChecksum de integridade
Anexar debuggerx64dbg, Cheat EngineAnti-debug
Injetar DLL de cheatInjector, LoadLibraryVerificação de módulos
Alterar valores em memóriaCheat Engine, trainerCifragem/ofuscação de variáveis + validação server-side
Speed hackAceleradores de clockChecagem de tempo + validação server-side
Forjar pacotesProxy, botHandshake assinado + validação server-side

Repare que validação server-side aparece em quase toda linha. Essa é a lição central: o cliente roda na máquina do inimigo e nunca será totalmente confiável. O anti-tamper eleva o custo do ataque e alimenta o servidor com sinais; o veredito final é do servidor.

Camada 1 — Integridade por checksum

A defesa mais barata contra edição do binário é conferir se ele é bit a bit igual ao que você distribuiu. Gere um hash forte do Main.exe original e verifique-o em dois lugares: no launcher, antes de iniciar, e no servidor, durante o handshake.

Passo 1 — Gerar o hash de referência

No Windows, com o binário final já pronto (já patchado com IP e versão corretos):

certutil -hashfile Main.exe SHA256

Guarde esse hash. Ele é a "verdade" contra a qual todo cliente será comparado. Sempre que você reeditar o Main.exe, o hash muda — automatize a regeneração para não distribuir cliente com hash desatualizado.

Passo 2 — Verificar no launcher

O launcher calcula o SHA-256 do Main.exe em disco e compara com o valor esperado antes de executar. Exemplo em C++ (esboço):

// Pseudocódigo — varia por season/cliente e por como você embute o hash
bool VerificarIntegridade(const wchar_t* caminho, const std::string& hashEsperado) {
    std::string hashAtual = CalcularSHA256(caminho); // via CryptoAPI / bcrypt
    if (hashAtual != hashEsperado) {
        MostrarErro(L"Cliente adulterado. Baixe novamente pelo launcher.");
        return false;
    }
    return true;
}

> Não embuta o hash esperado como string em texto plano fácil de achar. Ofusque, quebre em partes ou derive de outra coisa. Um atacante que localiza a string simplesmente troca pelo hash do binário editado dele.

Passo 3 — Checksum de seção em runtime (self-check)

Além do check em disco, o próprio cliente pode conferir a soma da sua seção de código (.text) em memória enquanto roda. Isso pega patches aplicados após a carga (injeção de código). A ideia: no build, calcule o CRC/hash da seção .text e, em runtime, recalcule periodicamente comparando com o valor gravado. Se divergir, reporte ao servidor.

Como o .text é mapeado com relocations e o valor esperado precisa bater, esse check normalmente exige controle do processo de build ou um protector que já faça isso por você (ver Camada 6).

Camada 2 — Anti-debug

Cheat Engine e x64dbg dependem de anexar um debugger ao processo. Detectar essa presença encarece a análise dinâmica.

Passo 4 — Checagens básicas

// Exemplos clássicos — combine vários, nunca confie em um só
bool DebuggerPresente() {
    if (IsDebuggerPresent()) return true;

    BOOL remoto = FALSE;
    CheckRemoteDebuggerPresent(GetCurrentProcess(), &remoto);
    if (remoto) return true;

    // PEB->BeingDebugged e NtGlobalFlag também são checados por proteções mais fundas
    return false;
}

Passo 5 — Detectar ferramentas por janela/processo

Varra janelas e processos por assinaturas conhecidas (nomes de classe e títulos de Cheat Engine, x64dbg, OllyDbg, Process Hacker). Mantenha a lista externa e atualizável, porque nomes mudam.

> Não trave o cliente ao detectar. Overlays de gravação, ferramentas de acessibilidade e até alguns antivírus disparam esses checks. O padrão seguro é reportar ao servidor com o sinal e deixar o ban para análise humana ou heurística acumulada. Matar o processo na hora é a receita de fórum cheio de reclamação de jogador legítimo.

Camada 3 — Verificação de módulos carregados

Cheats frequentemente entram como DLL injetada. Enumerar os módulos do processo e comparar com uma allowlist detecta injeções óbvias.

Passo 6 — Enumerar e classificar módulos

// Esboço — a allowlist varia MUITO por season/cliente e por drivers do usuário
void VarrerModulos() {
    // EnumProcessModules -> para cada módulo, GetModuleFileName
    // Classifique: sistema (system32), do próprio cliente, e "desconhecido"
    // Módulos desconhecidos e não assinados -> sinal para o servidor
}

Cuidado com falsos positivos: overlays (Discord, Steam, GPU), IMEs e software de áudio injetam DLLs legítimas. Por isso a saída ideal é um relatório ao servidor com os módulos suspeitos, não um bloqueio local cego. Assinar digitalmente e conferir a assinatura (Authenticode) reduz muito o ruído.

Camada 4 — Proteção de valores em memória

Trainers editam HP, zen, coordenadas e velocidade direto na RAM com Cheat Engine. Você não impede a leitura, mas dificulta a escrita útil.

  • Não guarde valores sensíveis em texto plano. Armazene HP, zen e velocidade cifrados/ofuscados e decifre só no uso. Cheat Engine acha o valor 1000 fácil; achar o valor cifrado que muda de representação, nem tanto.
  • Guarde uma cópia sombra. Mantenha um segundo valor derivado (soma de verificação) e, periodicamente, confira se batem. Divergência = alguém escreveu direto.
  • Valide no servidor. HP, zen, posição e velocidade que só existem no cliente são inúteis: o servidor deve ser a autoridade. Se o cliente diz que andou 50 células em 100 ms, o servidor rejeita, independentemente de qualquer proteção local.

Camada 5 — Handshake assinado com o servidor

Esta é a camada que o atacante não controla, e por isso a mais valiosa. Em vez de confiar que o cliente é íntegro, o servidor exige uma prova a cada sessão.

Passo 7 — Desafio-resposta na conexão

  1. Ao conectar, o ConnectServer/GameServer envia um nonce aleatório (valor de uso único).
  2. O cliente combina esse nonce com o hash do próprio binário e com um segredo embutido, e responde com um HMAC.
  3. O servidor recalcula o HMAC com o hash esperado e o mesmo segredo. Se não bater, recusa a sessão.
Servidor -> Cliente : nonce = 0x9F3A...   (aleatório por sessão)
Cliente  -> Servidor: resp = HMAC_SHA256(segredo, nonce || hashBinario)
Servidor            : recalcula e compara. Diferente => derruba a conexão.

Como o nonce muda toda sessão, um atacante não pode gravar uma resposta válida e reproduzir depois (anti-replay). E como o servidor conhece o hashBinario esperado, um Main.exe editado produz HMAC diferente e é barrado — mesmo que o atacante tenha neutralizado o check local.

> O segredo embutido no cliente é o elo fraco: quem engenharia reversa o binário pode extraí-lo. Rotacione o segredo a cada atualização de cliente, combine-o com dados de build e trate-o como algo que eventualmente vaza. A força real vem de somar isso à validação de comportamento no servidor.

Camada 6 — Packers e protectors comerciais

Se você não tem o código-fonte do cliente, os protectors aplicados ao binário pronto entregam grande parte das camadas 1, 2 e parte da 4 de uma vez.

FerramentaFocoContrapartida (exemplo)
ThemidaAnti-debug, virtualização, integridadePesado; falsos positivos de AV; inicialização lenta
VMProtectVirtualização de trechos críticosPerda de FPS se virtualizar código quente
Enigma ProtectorIntegridade, licenciamento, anti-dumpConfiguração extensa

Regras de ouro ao usar protector: virtualize apenas as rotinas críticas (handshake, checks), nunca o loop de render, senão o FPS despenca em máquinas fracas; mantenha uma build interna sem proteção para você depurar; e teste antivírus antes de lançar, porque packers disparam heurística e você precisará de whitelist/reputação.

Erros comuns e soluções

SintomaCausa provávelSolução
Cliente fecha ao abrir para muitos jogadoresAnti-debug agressivo pegando overlay/AVTrocar bloqueio por report; refinar allowlist
Antivírus deleta o Main.exePacker sem reputaçãoAssinar binário; submeter para whitelist; reputação no VirusTotal
Hash sempre inválido no launcherHash de referência desatualizado após reediçãoAutomatizar regeneração do hash no build
FPS caiu muito após protegerVirtualização do loop de renderVirtualizar só rotinas críticas
Handshake recusa clientes legítimosRelógio/nonce dessincronizado ou versão erradaConferir tolerância de tempo e AcceptVersion
Falso positivo com Discord/SteamVerificação de módulos cegaAssinar/allowlist módulos assinados conhecidos
Segredo do handshake vazouString em texto plano no binárioOfuscar/rotacionar segredo a cada update

Distribuição e rotação

Proteção não é "configura e esquece". Cada nova versão do cliente deve gerar novo hash, novo segredo de handshake e, se possível, pequenas variações nas rotinas de check para evitar que uma solução pública de bypass valha para sempre. Distribua sempre pelo launcher (que valida antes de rodar), publique o hash junto ao download e escaneie o binário final antes de subir. Trate cada bypass reportado no seu Discord como um bug de prioridade alta.

Checklist de lançamento

  • Backup Main_original.exe guardado fora da pasta do cliente
  • Hash SHA-256 de referência gerado a partir do binário final
  • Verificação de integridade ativa no launcher (hash ofuscado)
  • Anti-debug em modo report, não em modo kill
  • Verificação de módulos com allowlist de assinados conhecidos
  • Valores sensíveis (HP/zen/velocidade) cifrados no cliente
  • Validação server-side de HP, posição, velocidade e pacotes
  • Handshake nonce + HMAC ativo no ConnectServer/GameServer
  • Segredo do handshake rotacionável e ofuscado
  • Protector aplicado só em rotinas críticas (FPS testado em PC fraco)
  • Binário assinado e submetido para reputação de antivírus
  • Testado em máquina limpa, separada da de desenvolvimento
  • Build de debug interna sem proteção guardada para você depurar
  • Plano de rotação de hash/segredo a cada atualização documentado

Perguntas frequentes

Anti-tamper substitui o anticheat do servidor?

Não. O anti-tamper protege o binário do cliente e a memória local, enquanto a validação server-side confere se ações e valores recebidos fazem sentido. São camadas complementares: um cliente blindado com servidor ingênuo ainda cai por pacotes forjados, e vice-versa. Sempre valide no servidor além de proteger o cliente.

Posso usar Themida ou VMProtect no Main.exe?

Sim, packers comerciais como Themida, VMProtect e Enigma são bastante usados para dificultar engenharia reversa e debugging. O custo é maior consumo de CPU/RAM, tempo de inicialização mais lento e falsos positivos em alguns antivírus. Teste desempenho em máquinas fracas antes de lançar e mantenha uma build de debug sem packer para você mesmo depurar.

O checksum do cliente pode ser burlado?

Um atacante determinado sempre pode neutralizar um check local, porque o código que verifica roda na máquina dele. O objetivo do anti-tamper não é ser inquebrável, e sim elevar o custo do ataque e permitir que o servidor detecte inconsistências. Por isso o handshake assinado com o servidor, que o atacante não controla, é a parte mais valiosa.

Anti-debug vai atrapalhar jogadores legítimos?

Pode, se for agressivo demais. Técnicas como IsDebuggerPresent e checagem de janelas de ferramentas raramente afetam jogadores, mas travar o processo ao detectar qualquer coisa suspeita gera falsos positivos com overlays, gravadores de tela e software de acessibilidade. Prefira reportar ao servidor e deixar a decisão de ban para análise, em vez de matar o cliente na hora.

Preciso recompilar o Main.exe para adicionar proteção?

Depende. Se você tem o código-fonte do cliente (raro), compila a proteção junto. Sem fonte, o caminho é aplicar um packer/protector externo ao binário e, se houver suporte via loader ou DLL injetada pelo seu launcher, adicionar checks nesse componente. A verificação de integridade e o handshake podem viver no launcher e no ConnectServer sem tocar no Main.exe.

GA
Editor de guias e builds

Gabriel cobre gameplay, builds de classes, PvP e progressão. Testa cada estratégia em servidor antes de publicar.

Continue lendo

Artigos relacionados