Afinal de contas, é possivel descompilar um programa feito em Delphi de forma a obter o código fonte exato a que foi concebido? NÃO! Será possivel futuramente? Com certeza! Não achem que isto será impossivel pra sempre porque não existe nada neste mundo que é eterno. Tem muita gente trabalhando 25 horas por dia, em cima de codificação braba e algoritmos pesados, para obter esta preciosa e cobiçada ferramenta e chegar até ela é apenas uma mera questão de tempo. Então, o que existe nos dias de hoje? Por enquanto só programas que recuperam apenas as telas e as informações das classes utilizadas, informações estas que se limitam somente ao nome de algumas classes e metodos. Só que para obter isto voce não precisa de um descompilador, basta ter o M$ Visual Studio que permite que voce abra um executável dentro do seu IDE e tire dele não só telas como imagens, icones, glyphs, strings e outros recursos. Mas código fonte? Sem chances! Quando um projeto de Delphi é compilado para gerar o executável, a maioria dos nomes de funções, variáveis, constantes e classes são convertidos em ponteiros e a sintaxe do código é toda convertida para instruções ASM, o que seria muito dificil um descompilador reverter todo este processo para o fonte original exato. Porque isto acontece? Não sei se voce se lembra, mas uma das grandes vantagens do Delphi é a performance de um programa compilado com ele. Isto se deve ao fato de que o compilador "lê" o seu código fonte e gera código ASM referente àquela instrução. Uma forma de voce visualizar isto que estou falando, é criar um programa simples, algo que tenha apenas um evento e um IF, e depois mandar rodar dentro do IDE este programa. Feito isto, e com este programa em execução, voce vai abrir a janela de debugação "CPU" (Turbo Debugger), que voce irá encontrar no menu "View | Debug Windows | CPU". Todo aquele código assembler, que está sendo exibido ali, foi gerado pelo compilador para executar as instruções que você definiu nas Units. Este recurso é muito util para programadores assembler experientes que podem debugar instruções ASSEMBLER diretamente no projeto em busca de algum bug que não tem explicação lógica no fonte original. Mas analisando este código no Debugador, voce poderá observar algumas curiosidades, tais como o tanto de código que é gerado para a execução, por exemplo, de um simples bloco protegido Try..except..end ou um mísero StrToFloat ou IntToStr... Agora observe o conjunto de instruções abaixo:
mov
Este é o código de um simples If. Por ser uma linguagem baixíssimo nível, não existem comandos específicos, como if ou while, tudo é feito atravéz dos valores nos registradores. Portanto, escrever um programa para Windows, em assembler, você gastaria no mínimo 2 anos para concluí-lo e começar a fazer testes a procura de bugs. isto se não houverem contratempos ou alterações no projeto (O que é costumeiro por parte do cliente) até lá. Ou seja, nos dias de hoje isto é totalmente inviável, diria que impossivel, uma vez que assembler não tem bibliotecas, componentes ou VCL's como alguns sonhadores acreditam. Para se ter uma noção do que é um projeto Delphi compilado e do que estamos falando, imagine que você tem um projeto com 22 linhas de código escrito. Este mesmo projeto compilado, e depois linkeditado, ficará com aproximadamente 15.000 linhas. Agora imagine um programa em Delphi que tenha 10 mil linhas de código escrito dividido em 30 Units fora os Resources e a VCL? Imagine então descompilar um projeto gigantesco de umas 30 a 50 mil linhas de código escrito e depois sair vasculhando este código a procura de alguma coisa para ser alterada. Além disso tudo, não basta você trazê-lo para o Assembler, você TEM que SABER e DOMINAR Assembler! E MUITO! Só que quando você já domina por completo o Assembler, voce também não irá mais precisar de usar um descompilador para Delphi, basta dar um dump na memoria, usando o Debug do Dos, com o programa rodando que lá você vai achar tudo o que está precisando ou procurando. ![]() O DeDe (Delphi Decompiler) Descompila um EXE mas retorna tudo em código assembler sem definição de Units ou Forms COMO FICA UM CÓDIGO DE UM PROJETO COMPILADO NO DELPHI EM ASSEMBLER? Veja este exemplo:
push
ebp
00402FBC
Este código captura o valor de uma tecla, e o passa para uma variável, no caso do projeto, numa panel. Veja agora, que código Delphi, esse código Assembler representa:
procedure TKEYVIEW.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
Importante observar, que o código Assembler na verdade é maior. Neste código apresentado, ele está supondo que certas condições já existam. Este projeto, depois de compilado e revertido para Assembler, ficou com 9.471 linhas em assembler. Você consegue se imaginar descompilando um sistema inteiro ??? Imagina então tentar descompilar um ERP tipo o Advanced Protheus da Microsiga? E OS DESCOMPILADORES QUE CRIAM O .PAS.. ?? Alguns descompiladores para Delphi regeneram o .PAS, porém, só traz as declarações em pascal, o código ele traz em Assembler. Veja o exemplo:
procedure TKEYVIEW.FormKeyDown(Sender: TObject; Shift: TShiftState);
Alguns descompiladores tentam explicar cada parte do código, veja o exemplo:
procedure TKEYVIEW.FormKeyDown(Sender: TObject; Shift: TShiftState);
Este código é até muito interessante para quem gosta de estudar o comportamento de um compilador pois, Podemos ver que certas funções são montadas em blocos protegidos e coisas assim. ![]() O Dcu2Pas chega bem perto do fonte. Ele descompila um .dcu mas retorna em código assembler (Ainda que devidamente bem comentado) Tem mais! Quase todos os descompiladores que exitem, costumam trazer lixo junto com o código assembler. São instruções pertencentes à Area de Stack, paginação, Espelhamento de instruções e semáforos do sistema operacional e que podem vir junto com o código gerado na saída e que nada tem haver com o programa. Vamos ver outro detalhe de como o compilador monta estas instruções: Suponha um exemplo em que voce tem um executável cujo tamanho dele é de 2.945 kb, aí voce inclui mais dois forms, compila, e o executável ficou com 2.983 Kb, ou seja, é pouca diferença, para a inclusão de 2 forms. Qual a razão disto? Depois que o Delphi já utilizou uma vez um componente (um formulário, um timer, um button, etc) ele já incluiu o código necessário para se usar aquele objeto, o que acrescenta de tamanho do segundo em diante é só chamadas à este objeto ou instruções adicionais acrescentadas pelo programador no seu próprio código. O restante, o delphi já tem do primeiro componente incluído. Tudo isto prova que a sintaxe do fonte NÃO ESTÁ DENTRO DO EXECUTÁVEL como muitos pensam para acreditar em milagres deste tipo. Para que um descompilador de Delphi possa funcionar perfeitamente, ele teria que recriar todas as constantes, variáveis, funções, e procedimentos tudo isto a partir de instruções de máquina e ponteiros. Até mesmo se um certo grau de sucesso fosse alcançado, como alguns programas conseguem, o código "fonte gerado" seria incompleto e de dificil interpretação pois faltaria muita coisa que possa ter sido descartada na geração do executável. Existirá tambem o risco do descompilador não encontrar todo o codigo escrito ou encontrar apenas parte dele retornando um fonte alejado ou incompleto, ou então, misturar lixo no código gerando um fonte inutil e completamente ilegível. Agora imagine tentar recompilar esta lambança toda... O que acontece é que grande parte do pessoal, que mexe com delphi hoje, é oriundo do clipper e acha que ambas as linguagens possuem conceitos idênticos. O clipper, na verdade, nunca gerou um executável e sim um pseudo-executavel onde o seu codigo fonte (.prg) era convertido em um codigo de simbolos interpretados (.obj). Na linkedição, este arquivo .obj era incorporado à um arquivo .exe e junto iam também o interpretador dBase, que irá interpretar o código, bibliotecas do sistema operacional e bibliotecas do linkeditor com o propósito de gerenciar o executável na memória (Lembra dos "Overlays dinamicos"? ). Pois é, neste caso era muito facil voce fuçar o Executável, achar os arquivos .obj's lá dentro e depois passar estes arquivos em um programa que fizesse o inverso do compilador, ou seja, tranformar os simbolos em codigo ASCII (a fonte). Com o VB o processo é mais ou menos o mesmo e ainda por cima um ele não faz como o clipper que incorpora o interpretador no executável. No caso do VB, o interpretador está em forma de dlls "run times" (as VbRun300.dll, VbRun500.dll ) que são indispensáveis para que o programa seja executado em uma outra maquina. Mas com o Pascal (Que virou Delphi), com o C++ e com o Assembler isto não funciona pois, como já foi falado acima, os compiladores destas linguagens não geram símbolos interpretados e sim código nativo de maquina a partir do seu codigo fonte. Além do mais, não existe e nunca existiu um descompilador que desmonte o código 100% exatamente como foi escrito. Desde os tempos do Clipper quando usavamos Valkirie, Rescue, Unclip, todos eles nunca conseguiram fazer isto. Se no processo de descompilação, fosse encontrada uma função, escrita em C ou em Assembler, ela não era descompilada e sim substituida por uma declaração do descompilador muitas vezes chamada de ISNUL ou ISNIL e coisas do tipo. Também nomes de constantes e conteúdo de arquivos Header's (os .CH) não eram recuperados. Outro fato é que os descompiladores do clipper jamais geravam o código fonte da forma que foi escrito e sim na forma .PPO, código fonte em formato do pré-processador, facil de ser lido por programadores experientes mas complicado para os iniciantes. Hoje continuamos a ver a mesma estoria e um monte de gente acreditando na possibilidade dela existir, Os famosos EXE2DPR e EXE2DCU, FORMSPY ou EXE2DPK não geram e nunca geraram o código fonte na forma original como ele foi escrito, eles apenas desprendem os forms da aplicacao e nas units apontam os endereços onde o algorítmo está guardado, aí voce é obrigado a ter profundos conhecimentos de memória, endereçamento, lógica e manipulação de ponteiros e principalmente de Assembler para saber onde ir e como obter tal informaçao, pois, obviamente, ela estará em codigo assembler. Outras ferramentas tipo o Revendepro, tambem prometeram demais o que nunca conseguiriam cumprir. Alguns destes até que conseguem desmontar alguma coisa, mas é um código que não tem muito haver com o original, um fonte cheio de lixo com instruções absurdas totalmente sem lógica e que não são recompiladas. A ilusão é tanta, por parte destas pessoas, que elas acabam mesmo é caindo na conversa dos picaretas que, como em todo lugar, ficam de plantão na expreita de um otário pra cair no 171 deles. Existe uma história contada no meio, onde um programador chegou a fazer um depósito para ou suposto hacker ou cracker, sei lá, que dizia ter um descompilador para Delphi 100% eficaz. Após feito o depósito e enviado o comprovante via e-mail para uma conta WebMail, o programador recebeu um programa que recuperava apenas os .DFM's. DFM's esse, que pode ser recuperado por um programa que vem no diretório Demos do Delphi, o ResXplo, ou então com qualquer uma das zilhões de ferramentas extratoras de resources que existe na WEB e que são todas Freeware. Mas é como diz o ditado: "Assombração sabe para quem aparece..." No próprio site do EXE2DPR tem uma citação que diz o seguinte: "If you lose your Delphi 3.0/4.0 project source, but remain executable file, then this tool can rescue part of lost sources. Rescuer produces all project forms and data modules with all assigned properties and events. Produced event procedures don't have a body (it's not a decompiler... yet:) ), but have an address of code in executable file. In most cases, I " Isto quer dizer que ele recupera os forms, os Data Module, os eventos e procedures mas o CORPO DA PROCEDURE (O Algoritmo), ele não consegue pois isto não é possivel ainda. MAS PORQUE ESTES SUPOSTOS DESCOMPILADORES SOMENTE DESPRENDEM FORMS DO EXECUTÁVEL SE VOCE DISSE QUE O CÓDIGO É PURO DE MÁQUINA??? Forms, Bitmaps e Icones fazem parte da tabela de recursos do arquivo conhecido como "Resource" (.res). O que são Resources ??? Resources contem as informações que não podem ser compiladas por já estarem em código binário. Como as imagens cujo conteúdo é o seu proprio conjunto de bits. As imagens não são criadas em formato ASCII. O compilador só compila as instruções escritas em código ASCII para instruções x86. O que já tá em codigo x86 ele não mexe, apenas anexa e aponta dentro do executável pra onde esta coisa tá. Todo programa Win32 tem resources, onde são normalmente encontradas: a tabela de recursos aceleradores, os cursores, ícones, caixas de dialogo (janelas), fontes, menus, mensagens de erro e finalmente, as informações de versão. Na resource de um arquivo, todos estes itens podem ser lidos e modificados porque estão em uma área a parte do executável e incorporadas lá na forma original a que forma incluídas durante o processo de compilação e linkedição. Lembra-se do que falei do processo de montagem do executável no clipper?? Pois é! é a mesma coisa para ESTE CASO Como podem ver, acreditar em Descompilador para Delphi ou para C++ que retorne o código fonte na saída, é o mesmo que acreditar em Papai Noel, Duende ou no Monstro do lago Ness... Áh, e tem mais! Se um dia você conseguir descompilar um programa compilado no Delphi ou mesmo no C++ Builder e obtiver o codigo fonte daquele produto, saiba que isto que voce fez é CRIME, dá cadeia, um puta processo nas suas costas e de quebra uma multinha de arrancar o couro...HEHEHEHE.
Veja mais informações sobre o tal "Descompilador" que não descompila nada em:
|
E-Mail: walterchagas@yahoo.com |
![]() |