Eu tenho usado o Unity para criar um jogo 2D que será completamente offline (que é o problema), o jogo precisa que você insira certas strings em certos níveis e o Unity compila para DLLs, que podem ser facilmente modificadas com engenharia reversa, por isso é existe uma maneira de proteger essas cordas (o jogo está offline, então não consigo recuperar de outra fonte)?
O jogo depende muito dessas seqüências, e sim, eu estou ciente de Ofuscação, mas quero algo mais robusto. E eu sei que a saída mais fácil seria fazer tudo on-line a partir de uma fonte de dados, mas eu queria saber se é possível.
unity
c#
anti-cheat
TheBinaryGuy
fonte
fonte
strings
programa para ele.Respostas:
Não armazene essas strings, armazene o hash (criptográfico) delas.
Uma função de hash (criptográfica), como criptografia, é uma maneira de transformar uma string em "sem sentido" (chamado de hash), mas, diferentemente da criptografia, você não pode obter a string original desse hash (a menos que possa fazer força bruta ou o hash função está quebrada). A maioria das funções hash (se não todas) utiliza uma sequência de comprimento arbitrário e retorna uma sequência de comprimento constante (depende da função).
Como você verifica se uma sequência inserida pelo usuário é a correta? Como você não pode obter a sequência válida do hash, a única coisa que você pode fazer é fazer o hash do palpite do usuário e compará-lo com o hash correto.
Aviso (de Eric Lippert): NÃO USE a função incorporada
GetHashCode
como tal - seu resultado pode diferir entre diferentes versões e plataformas .NET, fazendo com que seu código funcione apenas em versões e plataformas específicas do .NET Framework.fonte
O que você está tentando fazer é inútil e inútil.
É inútil porque não há como ocultar adequadamente as informações que estão na máquina do usuário. Qualquer pessoa dedicada o encontrará. Você pode dificultar, mas nunca pode impedir. Se você criptografá-lo, precisará armazenar a chave e o algoritmo de criptografia em algum lugar. Não importa quantas camadas de criptografia você adicione, a camada mais externa sempre precisará ser criptografada para que o jogo seja executado.
Também não faz sentido, porque estamos vivendo na era da internet. Quando o seu jogo se tornar popular remotamente, esses códigos serão publicados em toda a web.
Tudo o que você pode fazer é confiar no jogador para não estragar sua própria experiência de jogo, procurando informações que o jogo ainda não deve lhes contar. A grande maioria dos jogadores não começará a engenharia reversa do seu jogo de qualquer maneira. E se os poucos que têm as habilidades necessárias fazem isso, a culpa é deles.
fonte
Se uma coisa dessas for realmente desejada, em vez de usar hash, considere construir as strings a partir de um valor de entrada numérico no tempo de execução.
A vantagem é que, como apontado pelo @Philipp, é um pouco inútil tentar ocultar códigos no executável se você puder esperar que eles sejam publicados na Internet de qualquer maneira. Com hash ou não, a mesma palavra encontrada na internet e inserida no jogo fornecerá o mesmo hash e funcionará de qualquer maneira.
Exceto ... exceto se o código de outra pessoa não funcionar para você. O que você pode fazer de maneira trivial - não 100% à prova de violações, mas é razoavelmente difícil de solucionar para o usuário comum. Qualquer coisa tão simples quanto o "gerador de nomes Elven Online" fará (pode ser arbitrariamente simples, realmente não precisa de muito mecanismo de geração de texto markov, puxar 4-5 sílabas de uma lista aleatória é bom o suficiente).
Basta gerar um número um tanto específico do usuário ou específico da máquina, ele nem precisa ser perfeitamente exclusivo ou muito resistente a violações. Algo que provavelmente é diferente para a maioria das pessoas e provavelmente não muda regularmente, por exemplo, o nome da rede do computador, o endereço MAC ou o GUID da unidade de disco do sistema, seja qual for (o número de série da GPU pode ser muito ruimidéia, pois os usuários provavelmente atualizarão as GPUs). Acrescente a isso o código numérico ao qual o código de desbloqueio se refere e alimente-o no seu gerador de palavras. Mas esteja preparado para responder a perguntas de suporte quando os jogadores usam dois computadores ou alteram sua placa de rede (o que é incomum, mas não impossível). Pode ser um bom plano gerar o ID aleatório apenas uma vez e armazená-lo com as configurações do jogo. Dessa forma, pelo menos não interrompe as instalações existentes na mesma máquina se algo mudar.
Ou então, você pode apenas usar o número de série do jogo, que é único e funcionará se o usuário alterar o hardware (ironicamente, no entanto, isso pode promover a pirataria, pois os códigos de desbloqueio compartilhados funcionam para seriais pirateados, mas não para clientes legítimos!).
Observe que impedir os usuários de trapacear não é necessariamente uma coisa boa. Em um jogo offline (ou seja, não competitivo), normalmente não há problema se o usuário trapaceia e obtém os códigos de algum lugar, em vez de jogar. Ele está apenas se enganando. Quem se importa.
Por outro lado, atrapalhar demais se realmente deseja trapacear é uma ótima oportunidade para irritar completamente os clientes pagantes.
Então ... antes de fazer algo dessa maneira, pense muito bem se você realmente quer isso e o que deseja. Possivelmente, ter cordas legíveis por humanos (ou trivialmente tornadas "ilegíveis" com xor) é bom o suficiente e, de fato, preferível.
fonte
hash(serial + 1)
para obter um número correspondente ao primeiro código. Em seguida, alimente isso no seu gerador de palavras, que extrai, digamos, uma sílaba de uma lista de 16 para cada 4 bits de entrada. Lá vai você, "palavras" individuais para cada usuário.hash(serial+1)
após o download, o que impede o usuário de calcularhash(serial+1)
? Após o download do programa, o usuário tem acesso a tudo o que o programa faz.hash(serial + 1)
. E daí? Isso não é um problema. Olha, se alguém investe de uma a duas horas (provavelmente de 6 a 8 horas para um "usuário" típico sem experiência com desenvolvedor de software) apenas para se enganar, bem ... deixe-o. O problema é que isso funciona para uma pessoa, mas não para todos, e não é competitivo ... então, não há problema.Se você não precisa mostrar as strings, a ideia do hash provavelmente é o caminho a percorrer. Se, por outro lado, você precisar mostrá-los ao usuário, existem outras maneiras de evitar que eles apareçam na sua DLL diretamente.
Uma maneira de lidar com isso além de criptografar ou ofuscar as strings é quebrá-las. Talvez apenas tenha um dicionário ordenado alfabeticamente de todas as palavras possíveis de todas as strings do jogo. Em seguida, tenha um array em algum lugar que permita reunir as palavras na string de que você precisa, indexando o array de palavras. Dessa forma, você não tem as cordas completas em nenhum lugar do jogo. Não há nenhuma chave mestra necessária para descriptografar as strings. E os dados que informam a ordem deles podem estar em toda a sua fonte, se, por exemplo, cada função que usou uma string tiver apenas uma matriz de índices locais para a função. Não tenho certeza do quanto isso é prático no seu caso específico, mas é uma maneira de fazê-lo.
Você pode até ter uma sequência composta por algumas palavras, mas elas acabam sendo colocadas em diferentes ordens. Por exemplo, você pode precisar das 2 seqüências a seguir:
Sua lista de frases conteria "um urso" e "minha casa", mas você teria uma lista grande de outras frases que poderiam ser colocadas entre elas, para descobrir qual delas seria tão difícil quanto realmente descobrir o quebra-cabeça do jogo (ou o que seja). Por exemplo, as frases de ação podem ser "percorridas", "queimadas", "empurradas", "protegidas de", "me separadas de", "produzidas magicamente" etc.
Você pode trabalhar isso no seu jogo fazendo com que os índices se baseiem em algo que o jogador coletou ou fez. Portanto, não haveria uma lista principal de índices em nenhum lugar do jogo. Eles seriam gerados pelo jogador que jogava o jogo.
fonte
strings
o executável.