Dekompilace je zpětný převod binárního souboru na zdrojovou formu.
Nejdříve ta dobrá (nebo taky špatná - jak se to vezme) informace: Aplikace psané v Delphi (na rozdíl od aplikací v .NET - pokud nejsou obfuskované) nejdou převést zpět na úroveň zdrojáků, ale něco se přesto dá dělat.
Nejprve standardní varování: tento článek neslouží jako návod pro jakoukoliv ilegální činnost, ale jako poslední možnost záchrany pokud ztratíte zdrojáky, popř. pro prozkoumání co uvidí případný cracker.
Výsledkem dekompilace budou maximálně DFM soubory, unity s názvy funkcí (metod, tříd) a jejich obsahem bude různě komentovaný kód v assembleru a případně doplňkové informace jako seznam textů (pozor na hesla!), crossreference (odkud se který kód používá…) - nikdy nedostanete zpět zdrojový kód. Vygenerovaný kód nelze ani zpět přeložit, přesto Vám takový kód může uspořit x hodin času (DFM…).
V podstatě existují dva typy nástrojů:
- obecné, tj. nespecializované na Delphi jako je např. Win32dasm, IDA Pro nebo OllyDbg. Tyto nástroje nemají žádnou speciální podporu pro specifické uložení DFM v EXE a ani jiné speciální konstrukce Delphi.
- specializované, nejznámější je DeDe (DelphiDecompiler), další je např. IDR (Interactive Delphi Reconstructor).
IDR
Jelikož je DeDe celkem znám, napíši raději něco o IDR. IDR je relativně nový program, je stále ve vývoji a jeho specialitou jsou zvláštní definice symbolů pro každou verzi Delphi (20M - 70M na verzi) s autodetekcí verze až do Delphi 2009 (2010 je ve vývoji).
Po cca 20min dekompilaci cca 6MB EXE souboru jsem byl schopen zobrazit stromovou strukturu tříd v aplikaci, zobrazit DFM v textové formě i ve vizuální formě (tj. zobrazil se formulář) a např. u tlačítka byla možnost přejít na jeho obsluhu (resp. přejít na jakoukoliv událost u čehokoliv), kde byl k dispozici komentovaný asm kód s referencemi na VCL a RTL
Na ukázku úryvek:
007BB46E mov eax,dword ptr [eax+31C]; TfrmAres.rbName:TRadioButton
007BB474 mov edx,dword ptr [eax]
007BB476 call dword ptr [edx+0B4]; TRadioButton.GetChecked
007BB47C test al,al
>007BB47E je 007BB571
007BB484 lea edx,[ebp-40]
007BB487 mov eax,dword ptr [ebp-4]
007BB48A mov eax,dword ptr [eax+324]; TfrmAres.edtName:TDxEdit
007BB490 call TControl.GetText
007BB495 mov eax,dword ptr [ebp-40]
007BB498 lea edx,[ebp-3C]
007BB49B call Trim
007BB4A0 cmp dword ptr [ebp-3C],0
>007BB4A4 jne 007BB4C8
007BB4A6 mov eax,7BB794; 'Není vyplněný obchodní název!'
007BB4AB call 0048120C
007BB4B0 mov eax,dword ptr [ebp-4]
007BB4B3 mov eax,dword ptr [eax+324]; TfrmAres.edtName:TDxEdit
007BB4B9 call 00685AA8
007BB4BE call @TryFinallyExit
>007BB4C3 jmp 007BB688
originál:
…
if rbName.Checked then
begin
if Trim(edtName.Text) = '' then
begin
MsgWarning('Není vyplněný obchodní název!');
gFocus(edtName);
Exit;
end;
…
Dále lze procházet projekt dle unitů nebo formulářů, procházet RTTI typy, nebo uložit dissasembly do souboru atd. Doufám, že vývoj bude pokračovat.