Página 1 de 1

formas de fazer comparação de valores segura?

Enviado: Qua Abr 26, 2017 10:54 pm
por ricardogom
Calma ai, que vou explicar.
sei que as versões atuais do gm é muito difícil reverter um executável em um código fonte legível e próximo da programação original feita nativamente.
Os programadores focam em apenas ofuscar seus códigos fontes, porém nem sempre um programa é liberado somente pelo acesso ao código fonte.
o problema é que qualquer linguagem que é facilmente manipulada por pessoas no final acaba sendo convertida em linguagem de máquina.
vejo que muitos tem êxito em modificar um programa, através de endereços de memória e vão executando o programa passo-passo.
até baixei um desses debuggers, fiz um programinha simples pra testar e não consegui mudar para o programa passar direto sem comparar.

Vamos lá! ao que interessa

Código: Selecionar todos

//Exemplo: a  condição é a senha tem que ser correta para passar e caso contrário fechar o programa
If (password = '123456')
room_goto_next();
else
game_end

//Porém se invertemos essa condição qualquer senha irá passar e só será fechado quando a senha for correta.
//Quem for alterar uma condição fixa feita pelo programador.
//já sabe que JE = Igual e JNE = Não igual, basta apenas localizar aonde faz está comparação e inverter ou pular a verificação(um pouco mais complexo)
If Not(password = '123456')
room_goto_next();
else
game_end

O programador fica amarrado a isso, pois é única forma de comparar valores.
Será que tem outras formas de programar que evite o a inversão da comparação no executável em linguagem de baixo nível.

Re: formas de fazer comparação de valores segura?  Tópico resolvido

Enviado: Qua Abr 26, 2017 11:37 pm
por Superbomber
Uma das maneiras de se evitar engenharia reversa é inserir código lixo.
O ideal seria alterar o código do programa já compilado, existem programas para proteger contra engenharia reversa...
Mas supondo que não possa usar tal tipo de programa(não é de graça), uma solução é código lixo.

Caso não saiba o que seria código lixo, é basicamente um monte de instruções que.... Não fazem nada. :yes:
Literalmente nada, estão ali só para encher linguiça. Parece bobo lendo o código fonte, mas após ser compilado resulta em um monte de instruções extras que só estão lá para poluir o código e dificultar a leitura.

Um exemplo:

1) No create do objeto você pode definir uma variável que seu valor não se pareça nenhum pouco com uma senha.
Recomendo criptografar todos os valores do game, assim todas as strings serão semelhantes. (um monte de caracteres sem sentido)
Engine que pode lhe servir de exemplo: [Engine] Criptografia de dados

Código: Selecionar todos

// Create
senha = "Um4S3nh4Qu4lqu3r";
name = crypt("Joãozim", senha);
aquelaSenhaQueVocePrecisaChecar = crypt("AtalDaSenhaVidaLoka", senha);
msg = crypt("Erooooou!", senha);
2) A verificação + Código lixo:

Código: Selecionar todos

var a, b, c, d, e, f;
// password é a senha digitada pelo usuário, assim como no seu código.

if(password == "ovelhanegra"){
   scriptDeCodigoLixo();
   a = "Super";
   b = "bomber";
   c = a + b;
   d = 5 * 9;
   e = string(d);
   f = real( string(d * 5) );
} else {
   d = 15;
   f  = 22;
   scriptNOP();
}

scriptFazerAChecagemReal();

if(d == 15){
   scriptDeCodigoLixo();
}
Conteúdo de scriptDeCodigoLixo():

Código: Selecionar todos

switch(f){
   case 24: scriptNOP(); break;
   case 77: f = 24; break;
   case 99: a = 81; break;
}

if(a == 81){
   if(f == 99){
      scriptNOP();
   } else {
      f = 99;
   }
}
Conteúdo de scriptNOP():

Código: Selecionar todos

var a;
a = 7;
a *= d;
a += 1;
return a;
Conteúdo de scriptFazerAChecagemReal():

Código: Selecionar todos

var a;
a = 1111;
if(a == d){
   return a;
} else if(password != crypt(aquelaSenhaQueVocePrecisaChecar, senha)){
   show_message( crypt(msg, senha) );
   game_end();
}

Confuso? Espero que não. :flw:

EDIT:

Esqueci de dizer porque você precisa fazer uma senha que não se pareça com uma senha.
No fim das contas, o valor não-criptografado da senha estará em algum lugar do código.
A solução é você já inserir na variável a senha já criptografada.
Ao invés de chamar a função de criptografia.

Outra coisa é você definir várias "senhas" diferentes. Tipo isso:

Código: Selecionar todos

senha1 = "ashG5w123c _";
senha2 = "hs4adC4wBVX0v - &";
// [...]
senha9001 = "gsaK1saCX" // Senha já criptografada.

// checando a senha:
if(password == crypt(senha9001, senha2)) //....
A ideia é confundir, só imaginar como o código irá resultar.

Re: formas de fazer comparação de valores segura?

Enviado: Qui Abr 27, 2017 12:29 am
por ricardogom
Legal. parabéns! muito útil o exemplo.
criptografa uma string, esse código seu ai impede de fazer a inversão da condição?
O próprio GM faz isso quando ele compila o executável ele cria um arquivo com caracteres codificados.
ou seja por isso que não há decompiler para a studio eles mudaram a forma de compilação.
Os crackers não perde tempo decifrando códigos, eles jogam o exe dentro do debugger e tenta inverter a condição ou ignorar ela dando salto de endereço de memória.

Porém o tal do jump, não funciona pra todos casos.
pois se ele pular uma condição que crie um 'objeto necessário' o programa não funcionará direito.

Re: formas de fazer comparação de valores segura?

Enviado: Qui Abr 27, 2017 3:36 am
por Superbomber
Você podia pelo menos ter fingido que leu o que escrevi.
Vou tentar resumir: Insira código lixo.

É o menor que posso deixar o texto, lamento se for grande demais para o seu padrão.

Bem, antes de mais nada... Antes o GM não compilava o código, era um interpretador com todo o conteúdo jogado lá dentro. Sem remover sequer um comentário.

Agora, referente ao código lixo.
Vou citar como exemplo algo bem básico:

Código: Selecionar todos

if(a == b){
   c();
}
// Mesmo código acima já compilado:
mov eax, [0xFFFF2200]
mov ebx, [0xFFFF2300]
cmp eax, ebx
jne $+5
call 0x01020304
Para "burlar" o if, é simples de entender que é só alterar o jne substituindo por 2 NOPs, não é mesmo? Precisa nem ser um gênio para perceber isso.

Agora vamos supor que eu jogue um monte de código que não faz merda nenhuma(código lixo):

Código: Selecionar todos

if(a == 1){
   scriptComMaisCodigoLixo();
} else {
   b = 25;
}

if(a == b){ // c() tem que ser executado, senão o jogo fecha.
   c();
}

scriptComMaisCodigoLixo();
Código acima compilado:

Código: Selecionar todos

mov eax, [0xFFFF2200]
cmp eax, 1
jne $+7
call 0x01000304
jmp $+6
mov [0xFFFF2200], 25
mov eax, [0xFFFF2200]
mov ebx, [0xFFFF2300]
cmp eax, ebx
jne $+5
call 0x01020304
call 0x01000304
Mais difícil de entender agora, né?
E como eu disse, é um exemplo bem básico.

Outra coisa que você não leu, foi eu dizendo que existem programas para dificultar a engenharia reversa.
Se você está lendo esta linha, e não leu nada do que escrevi acima novamente. Recomendo a leitura. ;)

EDIT:
Legal. parabéns! muito útil o exemplo.
criptografa uma string, esse código seu ai impede de fazer a inversão da condição?
O próprio GM faz isso quando ele compila o executável ele cria um arquivo com caracteres codificados.
ou seja por isso que não há decompiler para a studio eles mudaram a forma de compilação.
Os crackers não perde tempo decifrando códigos, eles jogam o exe dentro do debugger e tenta inverter a condição ou ignorar ela dando salto de endereço de memória.
Sem querer dizer a verdade, mas já dizendo: Você queria um código pronto não é mesmo? Por isso não leu nada e pulou para o código, ai achou que tudo o que falei foi sobre criptografar a senha e soltou tamanha asneira.
Porém o tal do jump, não funciona pra todos casos.
pois se ele pular uma condição que crie um 'objeto necessário' o programa não funcionará direito.
Não é assim que funciona abiginho. Mas não o culpo, você não entende nada desse assunto mesmo. :sorrir:

Re: formas de fazer comparação de valores segura?

Enviado: Sex Abr 28, 2017 12:14 am
por ricardogom
Eu curti sua engine de criptografia de dados, será muito útil em futuros projetos.
Me desculpe se me expressei mal e talvez vc interpretou em tom de ironia

Confesso que dei uma lida meio por cima dos seus código e não tentei entender a lógica.

vc postou códigos da linguagem programada original convertida em 'assembly'. código de máquina.
realmente pra mim já é algo bem complexo entender esses códigos doidos.
porém o que me interessava é era evitar a inversão.  mesmo sendo leigo eu entendi como era feito o processo.

Fiz uns testes aqui e descobri que usando o Switch ou While em vez do if é mais eficaz.
while faz travar e switch não faz nada.