Blog

11-03-2011 14:30

Protegendo o seu programa e o seu bolso

Protegendo o seu programa e o seu bolso

 

 Caso você seja um desenvolvedor contratado por alguma empresa criando sistemas específicos para cada cliente talvez isto nunca seja uma preocupação séria pois há poucas possibilidades do sistema interessar outra pessoa física ou jurídica com características operacionais diferentes (não estou me referindo a código-fonte aqui mas ao produto acabado).

Mas caso você esteja no mercado de softwares para o público em geral, bem-vindo ao grande clube dos programas pirateados. Este artigo visa introduzir alguns conceitos de proteção de software para programadores em geral mas antes de começarmos há uma coisa muito importante sobre a qual gostaria de dizer: Muitas grandes empresas liberam softwares com baixa proteção contra pirataria exatamente visando uma divulgação indireta do produto (ocorre muito com componentes para Delphi, a maioria possui uma chave publicamente divulgada). É uma tática que dá certo em países aonde há uma certa lei e consciência por parte dos usuários com software mas isto acredito não se aplica ao Brasil.Um conselho: não faça isso ! Ninguém vai comprar aqui o seu produto e a quantidade que comprar não cobrirá os custo do desenvolvimento.

Você poderá distribuir o seu software como produto de prateleira ou como um shareware pela Internet. A grande vantagem do shareware é a divulgação boca à boca (ou seria clique à clique ?) que ele oferece mas o ideal é as duas abordagens ao mesmo tempo. Isto possibilita que o usuário que ficou hesitante em adquirir o produto na loja possa baixar e testá-lo. Obviamente nunca esqueça de divulgar o seu site na embalagem.

Para vender software, um bem intangível materialmente, é preciso um bom sistema de proteção pois o seu programa poderá virar um freeware em poucos segundo. É só encontrar um hacker que goste dele. Interessante é que dificilmente um hacker irá quebrar a proteção de um produto do qual não goste ou não use, portanto quando encontrar cracks para o seu programa em vários sites da web sinta-se elogiado ! Depois pode ficar triste por não ter recebido um tostão com o seu trabalho.

Algumas técnicas de proteção (os prós e contras)

Para avaliação do software:

Nag-Screen: O programa sempre exibe uma tela avisando que é uma cópia de execução restrita (ou algo semelhante) e solicita o registro do mesmo por um determinando período.

Prós: O Usuário sempre é lembrado com uma tela de aviso que está com uma cópia restrita ou não totalmente funcional. Alguns nag-screens apenas roubam um pouco do tempo de uso do software mas não chegam a atrapalhar o uso efetivo, o que é ótimo para o usuário: a lógica da comida grátis que vicia.

Contras: Se a limitação for apenas o nag-screen todo mundo se acostuma com ela e depois de um certo tempo até se esquece que ela existe. Não é eficiente.

Período: Um programa funciona dentro de um certo período de avaliação.

Prós: O usuário usará todo o software com todos os recursos e poderá testar tudo.

Contras: É comum o usuário esquecer que está com uma cópia de avaliação. Alguns softwares, com uma péssima proteção, podem ser contornados simplesmente voltando o calendário do sistema.

Recursos Chaves Desabilitados: O programa possui alguns recursos que não funcionam como opções para salvar, exportar etc.

Prós: O Usuário tem mais liberdade que todos os métodos acima e sempre que tentar fazer o salvamento de dados lembrará que está com um software não totalmente funcional forçando uma compra.

Contras: É uma das formas mais fáceis de um programa receber um crack para liberar o recurso protegido.

Para licenciamento do software:

Número Serial: O Programa possui um número único serial que o habilita completamente.

Prós: O usuário somente digita o serial e pronto, o programa está liberado. Ideal para softwares de prateleira aonde o usuário já adquiriu o produto. O sistema preferido para a divulgação indireta.

Contras: Centenas de outros usuários somente digitam o mesmo serial e pronto: centenas de programas registrados. Use esta forma caso não deseje receber pelo seu programa ou queira uma divulgação indireta do mesmo e esperar pela consciência do usuário, isso não funciona no Brasil. Centenas ou milhares de usuário podem usar o mesmo serial. Esta caindo em desuso rapidamente pois há centenas de sites com index sofisticados de seriais para qualquer programa o que torna o sistema quase completamente inútil hoje em dia.

HardLocks: Um pequeno dispositivo é colocado na porta serial, paralela ou USB com uma identificação única para liberar o funcionamento do sistema.

Prós: Um dos sistemas mais difíceis de serem quebrados e definitivamente o mais seguro. Garante a taxa de uma licença por máquina o que é o ideal. Para sistemas caros (algo acima de $1000,00) considere seriamente o uso de HardLocks.

Contras: Custo do HardLock por cópia licenciada e alguns problemas (raros) com periféricos usando aquela mesma porta, mas nada tão sério assim para prejudicar o usuário. As portas seriais e paralelas estão caindo em desuso com o USB e já existem HardLocks para elas também. Os Hardlocks pode apresentar defeitos dependendo do tipo.

Você deve adquirir um kit de gravação e um Hardlock para cada cópia de distribuição. Não é muito caro mas o seu software deve compensar isto obviamente.

Disquete de Habilitação: Um disquete é fornecido junto com o programa para a sua habilitação ou desabilitação.

Prós: É o hardlock dos pobres sem o mesmo nível de proteção.

Contras: Não faça proteção via disquetes de habilitação/desabilitação como o Dr. Case e outros. É perda de tempo ! Há vários utilitários que fazem a cópia perfeita do disquete sendo possível habilitá-lo em qualquer máquina. E ainda pode-se ter o problema de superfície no disco e um belo dia quando o usuário precisar instalar o software em outra máquina ele terá a surpresa do disco já mofado ou perdido. Tenha certeza que isto sempre acontece no final de semana quando ele liga para o seu escritório na segunda descarregando o seu vocabulário.

Identidade Única: Uma das melhores e mais eficientes tipos de proteções é de identidade do equipamentos recentemente implementado pela própria Microsoft. Isto consiste em recolher dados únicos sobre o seu computador como serial do HD, informação da BIOS (não aconselhável), Versão do OS, Nome do computador etc. Com base nestas informações você poderá gerar uma fechadura de identificação. Essa fechadura precisará de uma chave fornecida por você para habilitar o seu software unicamente para aquela máquina.

Prós: Difícil de ser quebrado quando bem implementado e permite alta adaptabilidade contra cracks criado contra o sistema como patchs invisíveis que permitem a modificação do sistema. Permite a taxa de apenas uma licença por computador.

Contras: Caso o usuário formate a maquina, modifique periféricos chaves o sistema pode desabilitar a cópia automaticamente. Isto cria problemas com a solicitação de uma nova licença para instalação. O usuário pode simplesmente ligar alegando este fato e de boa fé você terá que fornecer uma nova liberação.

Habilitação Pela Internet: Ao adquirir um produto o usuário recebe uma senha que permite a geração de um número para habilitação e instalação em uma máquina.

Prós: Após habilitar, o número é automaticamente invalidado para outros usuário o que evita o problema de divulgação do mesmo pela rede.

Contras: O seu site deve estar em um provedor 100% confiável ou esteja preparado para aquele cliente que comprou o produto no sábado a tarde e o seu site ficou fora do ar no domingo sem ele poder autorizar o software para o uso.

Conclusão

Não há método melhor ou pior na minha opinião para proteger um programa mas, mais trabalhoso ou menos trabalhoso para um hacker quebrar. O Ideal é que que você use duas ou mais técnicas para proteger o programa.

Há um princípio básico que ao se usar dois sistemas simples de proteção independentes cria-se um sistema forte de proteção. Por exemplo, caso use o sistema de data é fácil monitorar aonde se esta gravando esta informação (quando o programa foi instalado) e adiar o tempo limite de uso. Nag-Screens podem ser rastreadas e um hacker com bons conhecimentos de assembler pode editar diretamente o seu código binário fazendo jumps nas avaliações de restrições. Agora combinando duas ou três técnicas as coisas complicam para ele e talvez o trabalho não valha a pena (coisa que ele realmente não é acostumado).

Mas antes de começar a desenvolver o sistema de proteção para o seu programa, siga algumas dicas que aprendemos depois de muito prejuízo com pirataria.

1- Nunca coloque literalmente as mensagens referentes a registro, nag-screens, avisos de limitação e etcs, em um formato legível para um ser humano. Faça uma encriptação destas mensagens. Uma técnica bem simples dos hackers consiste em procurar no código binário por uma determinada ocorrência tipo " Cópia Trial" e perto tem um "IF" aonde se pode bloquear e lá se foi a sua proteção. Portanto, faça uma função de codificação e decodificação e grave todas as mensagens codificadas no seu programa (no código-fonte) sendo que as mesmas somente serão exibidas quando você chamar a função de decodificação.

2- Faça uma estampa no software. Ou seja, todos os programas possuem uma informação referente ao seu tamanho físico, data e hora de criação e CRC. Caso o seu programa tenha sido alterado após aquela data, através de uma função, o programa poderá verificar em sua estampa interna se ele foi modificado. Aqui pode ocorrer alguns problemas com programas anti-virus que usam a mesma técnica para monitorar alteração de executáveis aplicando uma "vacina" neles mas já é da responsabilidade do usuário.

3- Grave dados no registry sempre encriptados e, se eles forem sobre as informações de registro nunca coloque na mesma árvore das outras definições do seu software. Isto dificulta e muito as coisa. Mas se o hacker possui um programa de monitoramento do registry ele poderá facilmente contornar isto mas não antes sem um bom trabalho de adivinhação. E, nunca use chaves com nomes óbvios tipo "Serial", "SenhaPrograma", "DataLimite" e etc. Dê sempre preferência a gravar dados de configuração e autorização no registry do que em arquivos INI (lembra-se deles ?). O registry é mais difícil de ser manipulado por um leigo e é possível colocar chaves observando a mudança de outras chaves o que torna as coisas mais complexas.

4- Se possível, implemente um sistema periódico de verificação da licença via site na web.

Coloque este alerta em seu termo de uso do seu software e o faça de tal forma que seja invisível, indolor (não fique interrompendo o usuário) e que desabilite o software imediatamente ao verificar uma cópia com o número de série irregular ou divulgado. É importante aqui implementar nos CGI do site um alerta via e-mail quando ocorrer várias tentativas de liberação de um mesmo serial. Assim você descobre rapidamente quem vazou um serial para o público.

5- Tenha uma proteção não divulgada. Por exemplo, após o software executar 300 vezes uma mensagem surge do nada indicando o download de uma cópia mais atualizada. Nesta nova cópia você já deve ter contornado todos os problemas com cracks que apareceram no período.

6- Faça Check Point em pontos não óbvios do seu software e em vários lugares. Use uma periodicidade completamente aleatória para fazer isto. Por exemplo, quando o usuário abrir uma determinada tela não muito utilizada, ocorre uma verificação em background sobre a validade da licença esta verificação pode e deve ser aleatória. Após validar e algo estiver errado, nunca exiba no mesmo momento que a licença é irregular pois se torna uma referência para o Hacker aonde ele deve procurar no código binário para quebrar o seu programa. Lembre-se que tudo serve como marcação no código binário: um caption de um form, o conteúdo string de um controle etc.

7- Use constantes. Abuse delas em vez de escrever diretamente nos dialogs para comunicação com usuário. Faça uma Unit separada aonde somente é armazenado estas constantes. Isso confunde quem olha o código binário do executável pois fisicamente no executável elas não estarão próximas.

Todas estas informações foram adquiridas com a nossa experiência e, principalmente, com dicas de dois conhecidos especialistas em quebras de programas e criação de cracks. Na primeira divulgação de um dos nossos softwares um deles me retornou uma cópia crackeada em questão de horas (segundo ele, estava sem tempo por isso demorou tanto), e ficamos envergonhados para dizer a verdade. Depois ao implementarmos a codificação de string e outras técnicas, ele levou uma semana mas não conseguiu liberar todos os recursos. Ao ativarmos os sistemas randômicos de verificação em background e validação pelo site ainda não tivemos uma quebra. Claro que ela irá ocorrer, mas enquanto isto estamos recebendo pelo nosso trabalho.

Acho que seguindo estas dicas você terá uma boa chance de receber pelo seu trabalho na quantidade justa. Lembre-se que há uma legião de pessoas ai fora tentando quebrar a proteção pelo simples prazer de dizer que foram eles.

Portanto a questão não é fazer um sistema 100% seguro (o que é quase impossível) mas um que seja 110% trabalhoso para eles. Tenha em mente também que eles são em maior número e problema não é se vão quebrar a segurança mas quando e o que você vai fazer em seguida.

Não poderíamos terminar este artigo sem falar sobre alguns componentes para proteção.

Uma coisa que percebi é que certos componentes de proteção são tão complicados que você as vezes tem que passar uma semana implementando ele no seu sistema. Mas aqui estão alguns que são ótimos pela simplicidade e fácil implementação.:

OnGuard (TurboPower) - Não é propaganda pessoal ! Os componentes da TurboPower tem uma grande qualidade e o OnGuard faz tudo o que se precisa de proteção. Validação e criação de serial, limitação por data, estampa no executável, dias de execução e muito mais. A grande vantagem é que há exemplos para tudo que podem ser fácil e rapidamente adaptados.

Lock&Key - Gosto do Lock&Key pela sua simplicidade de uso. Ele gera uma "fechadura" com base nos dados do HD do usuário e com este número-fechadura você cria um número único para liberar o software. Trabalha com níveis o que é ideal para proteção progressiva. Não estamos usando mais este, apesar de sua boa qualidade.

SharewareIt - Crie sistemas de shareware de forma bem simples. A vantagem é que é gratuito.

 

Este artigo foi escrito por Murilo Oliveira, proprietário da FastByte.
Contou com a colaboração de Fred Montier.
21-01-2011 20:47

Programação em Delphi para Iniciantes

 

Introdução à Programação

Caso você já tenha uma base de programação pode pular esta parte, ou pode lê-la caso se sinta inseguro quanto ao seu conhecimento.
Bem, em primeiro lugar, o que este guia exige é uma noção de comandos básicos que todo (ou quase todo) tipo de linguagem exige.
Note que os exemplos serão baseados na programação Delphi, e não qualquer linguagem.

Variáveis

Variável é um nome conhecido por qualquer programador (ou pelo menos deveria ser), este nome significa um endereço na memória onde um certo valor fica guardado. Vejamos um exemplo: se você declara a variável i:

var i:integer; 

 ("var" é nome usado para declarar uma variável em Delphi, "integer" é o tipo de informação que ela deverá armazenar) daí você pode estabelecer um valor para i:

i := 12;  

este valor vai ficar "guardado na memória" para você poder usa-lo mais tarde, por exemplo, para fazer uma conta:

i := 4 * i;

Agora i vale 4 vezes 12 (48).

Loops

Se você já fez algum programa em uma linguagem qualquer deve se lembrar dos famosos FOR e WHILE (loop), caso contrário, vamos a uma introdução a estes comandos:
Em uma linguagem de programação, loop é um comando que faz com que um certo código seja executado enquanto uma certa condição for atendida, um exemplo o ajudará a entender melhor:

var i:integer; //(declara a variável i)
for i := 1 to 30 do
ShowMessage ('O VALOR DE "I" É: ' + IntToStr(I));

 
Este comando fará com que "PARA" (FOR) I = 1, ou seja, o valor inicial de i é 1, "ATÉ" (TO) 30 (inclusive) exiba uma mensagem (SHOWMESSAGE, é o comando de exibir mensagens) escrevendo o valor de i. Portanto serão exibidas 30 mensagens. O valor de i e incrementado automaticamente ao fim do loop. Veja:
for i := 1 to 30 do (i=1) => ShowMessage(...) => (retorna a origem) for i := 1 to 30 do (i=2) => ShowMessage (...) =>
(...)
for i := 1 to 30 do (i=30) => ShowMessage (...) => Fim do loop.

O comando While é semelhante, veja um exemplo de seu uso:

var k:integer; //(declara a variável k).
k := 0 //(define o valor de k como "0".
while k < 10 do
ShowMessage ('k é menor que 10');

 "QUANDO" (WHILE) k é menor que 10 exibe a mensagem "k é menor que 10" (a mensagem em Delphi realmente deve estar entre apóstrofos (aspas simples) e não aspas duplas (como em muitas linguagens)). No entanto este loop não deve ser usado desta forma, pois, ao contrário de "for", while NÃO incrementa automaticamente o número, portanto o loop nunca acabará, pois k é 0 e sempre será 0 (foi definido esse valor em "k := 0"). Portanto seria melhor fazer:

var k:integer; //(declara a variável k).
begin
k := 0 //(define o valor de k como "0". 
while k < 10 do
begin
ShowMessage ('k é menor que 10);
k := k + 1;
end;

 
Agora o valor de k será incrementado de 1 toda a vez que o loop "retornar", portanto depois de 10 mensagens o loop acabará (k vai de 0 até 9). Não se importe com o "begin" e "end" eles serão discutidos mais adiante.

Introdução a linguagem e migrando para Delphi

Variáveis

 Talvez programadores oriundos de outras linguagens tenham certa dificuldade para se acostumar com os padrões delphi. A declaração de variáveis e seu uso, provavelmente parecerá chato para programadores Visual Basic. Vamos a algumas regras práticas:

  1. Não é possível declarar variáveis em qualquer lugar, apenas no início do procedimento.
     

  2. Os tipos de dados Delphi não são compatíveis (como no VB), por exemplo, você não pode multiplicar a string "X" pela string "Y", mas sim transformá-las em números inteiros e depois multiplica-los, veja: Z := StrToInt(X) * StrToInt(Y);.

     

Nem mesmo números inteiros são compatíveis com reais.

Sinal de igual

 Não use o sinal de igual para atribuir valores (como em grande parte das linguagens) mas sim ":=" como na linha abaixo:

 i := 0;

 O sinal de igual é usado apenas para comparação como em comandos "If", veja:

 If i = 0 then
ShowMessage('O valor de i é 0');
else
ShowMessage('O valor de i não é 0';

 Note que não se usa o EndIf como no caso do Visual Basic, por exemplo... Mas pode-se usar o begin e end para determinar o início e o fim como em:

if i = 0 then
begin
ShowMessage('O valor de i é 0');
ShowMessage('Foi usado Begin e End porque foram utilizadas duas linhas');
end
else
ShowMessage('O valor de i não é 0';

 Quando se usa uma única linha não há necessidade de usar Begin e End.

IMPORTANTE

Você deve ter notado que em Delphi não se usam aspas duplas ("), mas aspas simples ('), ou apóstrofo, como preferir. Também é usado ponto e vírgula (;) no final de cada comando (mas não nos que terminam com comandos como If. Mas lembre-se que NÃO se deve usar ponto e vírgula antes de else.

 Outro motivo pelo qual no final de cada declaração usa-se o ponto e vírgula é para mostrar que acabou. Por esta razão pode-se continuar o comando na linha de baixo (menos partir strings ao meio), veja:

 Estaria CORRETO:

MessageDlg ('Esta é uma mensagem!',
mtinformation, [mbok], 0);

 Mas estaria INCORRETO:

MessageDlg ('Esta é uma
mensagem!', mtinformation, [mbok], 0);

 Se for necessário use:

MessageDlg ('Esta é uma' +
+ ' mensagem!', mtinformation, [mbok], 0);

Isso é correto.

Comentários

 Os comentários podem estar entre chaves:

{Este é um comentário que pode estar
em mais de uma linha}

 entre sinais de parênteses e asterisco, como o mostrado abaixo:

(* este é um comentário
que pode estar em mais de uma linha
até que seja colocado o sinal de asterisco e fecha parênteses *)

 Ou pode estar depois de duas barras, para comentários rápidos de apenas uma linha, veja:

// Este comentário não pode passar de uma linha...

Operadores

 Eles são:

* - Multiplicação aritmética.
/ - Divisão de números que obtém um número real (exemplo: 5/2 = 2.5).
div - Divisão de números que obtém um número inteiro (exemplo: 5/2 = 2).
+ - Adição.
- - Subtração.
= - Igual.
<> - Diferente.
> - Maior.
>= - Maior ou igual.
< - Menor.
<= - Menor ou igual.

 Exemplo:

Form1.Canvas.TextOut (1, 1, IntToStr((2 * 5) div 3));

 Form1: Nome do formulário;
Canvas: Propriedade (não apenas do formulário) relacionada com desenho. Neste caso ela é usada para escrever no formulário (com o TextOut), algo como o print do Visual Basic. Sua cor de fundo padrão é branca, mas é possível mudá-la acessando a propriedade brush. O primeiro parâmetro é o left, o segundo é o top e o terceiro é o texto a ser escrito.
IntToStr: Transforma um inteiro em caracteres (como já foi dito anteriormente, o Delphi não possui compatibilidade entre Integers e Strings, a não ser que sejam usadas Variants).

 Iniciantes:

Para quem ainda não está integrado com programação aqui vão alguns conceitos:
Parâmetros: São "valores extras", colocados entre parênteses para fornecer outras informações ao método (function ou procedure). No exemplo mostrado, a função precisa dos parâmetros inteiros (que foram determinado como 1 neste caso) para saber a que distância da margem esquerda e o topo, respectivamente;
Left: Valor inteiro que diz a distância até o canto esquerdo de um objeto;
Top: Valor inteiro que diz a distância até o topo de um objeto;


 

Dicas...

Usando funções externas (de DLLs)...

Usar funções externas, de uma ou mais DLLs é muito simples, basta declara-las da seguinte forma:

function NomeDaFuncao(Parâmetros: Tipo): TipoRetorno; stdcall; external 'NomeDaDLL';

Você pode ver o nome de uma função da DLL na Visualização Rápida do Windows (se esta estiver sido instalada), para isso encontre o arquivo DLL, clique nele com o botão direito do mouse e escolha visualização rápida.

Manipulando "Application"...

A classe TApplication proporciona muitas manipulações úteis do aplicativo como um todo. Por exemplo, caso você queira que quando um aplicativo for minimizado apareça a hora atual no título da barra de tarefas, e quando ele for restaurado não apareça, use o seguinte código no evento OnLoad do formulário, por exemplo:

Application.OnMinimize := ShowDate;
Application.OnRestore := NShowDate;
 
procedure ShowDate;
begin
TForm1.Timer1Timer(Sender);
Timer1.Enabled := True;
end;
 
procedure NShowDate;
begin
Timer1.Enabled := False;
Application.Title := 'Título do Aplicativo';
end;

Este exemplo considera que o aplicativo possua um relógio que atualiza de tempos em tempos (a cada 250 milésimos de segundo por exemplo). Este é desabilitado quando o formulário é restaurado.

Undo na caixa de texto (Memo)...

Use o seguinte código para Desfazer a última ação em uma caixa de Texto (Memo):

Memo1.Perform(EM_UNDO, 0, 0);

o valor retornado de Memo1.Perform(EM_CANUNDO, 0, 0) será diferente de zero se o comando de Desfazer estiver disponível.

Pegando a posição do cursor...

Use o seguinte código para ver a posição do cursor na tela, ele é muito útil quando o evento usado não possui como parâmetros "X" e "Y":

procedure GetPosition (var X; var Y);
var CPos: TPoint;
begin
GetCursorPos(CPos);
X := CPos.X;
Y := CPos.Y;
end;

 

© 2011 Todos os direitos reservados à Walmiro Fabiano Júnior.

Crie o seu site grátisWebnode