2010-05-25 12 views
10

Czy dekompilator jest czymś, co daje źródło skompilowanego/zinterpretowanego fragmentu kodu? Ponieważ dla mnie to brzmi niemożliwe. W jaki sposób uzyskasz nazwy funkcji, zmiennych, klas itp., Jeśli zostaną skompilowane. Czy błędnie interpretuję definicję? Jak to działa? A jaka jest główna zasada, która je wykonuje?Co to jest de-kompilator, jak to działa?

Odpowiedz

10

Masz rację co do definicji dekompilatora: wymaga skompilowanej aplikacji i dopasowania kodu źródłowego. Jednak w większości przypadków zna on nazwę i strukturę zmiennych/funkcji/klas - po prostu zgaduje. Analizuje przepływ programu i próbuje znaleźć sposób na reprezentowanie tego przepływu przez pewien język programowania, zazwyczaj C. Jednakże, ponieważ wybrany język programowania (C, w tym przykładzie) jest często na wyższym poziomie niż stan programu bazowego (plik wykonywalny binarny), niektóre części programu mogą być niemożliwe do przedstawienia w prawidłowy sposób; w tym przypadku dekompilator zawiedzie i będziesz musiał użyć dezasemblera. Dlatego wielu ludzi lubi zaciemniać swój kod: utrudnia to dekompilatorom otwieranie kodu.

Budowanie dekompilatora nie jest prostym zadaniem. Zasadniczo, musisz wziąć aplikację, którą dekompilujesz (czy to plik wykonywalny, czy inną formę skompilowanej aplikacji) i parsować ją w drzewo, z którym możesz pracować w pamięci. Następnie przeanalizowałbyś przepływ programu i spróbujesz znaleźć wzorce, które mogłyby sugerować, że instrukcja if instrukcja/zmienna/funkcja/etc była używana w określonej lokalizacji w kodzie. To naprawdę tylko gra polegająca na zgadywaniu: musisz znać wzorce, które kompilator tworzy w skompilowanym kodzie, a następnie wyszukiwać te wzorce i zastępować je równoważnym czytelnym dla człowieka kodem źródłowym.

Jest to znacznie prostsze w przypadku programów na wyższym poziomie, takich jak Java czy .NET, gdzie nie trzeba zajmować się instrukcjami montażu, a takie zmienne są w większości zadbane. Tam nie musisz zgadywać tyle, co bezpośrednio tłumaczyć. Możesz nie mieć dokładnych nazw zmiennych/metod, ale możesz dość łatwo wydedukować strukturę programu.

Nota prawna: Nigdy nie napisałem dekompilatora i dlatego nie znam wszystkich szczegółów tego, o czym mówię. Jeśli jesteś naprawdę zainteresowany pisaniem dekompilatora, powinieneś otrzymać książkę na ten temat.

+0

Jaka jest ogólna zasada, która kryje się za jednym? –

+0

W rzeczywistości często można uzyskać nazwy zmiennych dla języka Java i pliki GCC gotowe do pracy z debugowaniem. – paxdiablo

+0

@paxdiablo: Tak, dlatego włączyłem tam "w większości przypadków", ponieważ jest kilka przypadków, w których * można * faktycznie uzyskać kod źródłowy, który wygląda prawie identycznie jak oryginał. :) –

1

Decompiler zasadniczo pobiera kod maszynowy i przywraca go z powrotem do języka, w którym został sformatowany. Jeśli się nie mylę, myślę, że dekompilator musi wiedzieć, w jakim języku został skompilowany, w przeciwnym razie nie będzie praca.

Podstawowym celem dekompilatora jest powrót do kodu źródłowego; na przykład, jeden raz mój plik Java został uszkodzony i jedyną rzeczą, którą mogłem, aby go przywrócić, było użycie dekompilatora (ponieważ plik klasy nie był uszkodzony).

1

Działa poprzez dedukowanie "rozsądnej" (w oparciu o heurystyki) reprezentacji tego, co znajduje się w kodzie obiektowym. Stopień podobieństwa między tym, co produkuje, a tym, co pierwotnie było, zależy w dużej mierze od tego, ile informacji zawiera binarny, od którego zaczyna. Jeśli zaczynasz od "czystego" pliku binarnego, zwykle utknąłeś w tworzeniu "rozsądnych" nazw zmiennych, takich jak używanie takich indeksów jak i, j i k dla indeksów pętli i dłuższych nazw dla większości innych.

Z drugiej strony język obsługujący introspekcję musi osadzić znacznie więcej informacji o nazwach zmiennych, typach itp. W pliku wykonywalnym. W takim przypadku dekompilacja może wytworzyć coś znacznie bliżej oryginału, na przykład zwykle zachowując oryginalne nazwy funkcji, zmiennych itp.W takim przypadku dekompilator może często produkować coś podobnego do oryginału - prawdopodobnie tracąc niewiele więcej niż formatowanie i komentarze.

0

To zależy od tego, jaki język dekompilujesz. Jeśli dekompilujesz coś w stylu C lub C++, to jedyną informacją dostarczoną do ciebie są nazwy funkcji i argumenty (w bibliotekach DLL). Jeśli masz do czynienia z java, kompilator zwykle wstawia numery linii, nazwy zmiennych, nazwy pól i metod, i tak dalej. Jeśli nie ma nazw zmiennych, otrzymasz nazwy takie jak localInt1, localInt2, localException1. Lub cokolwiek jest kompilator. I może powiedzieć odstęp między liniami, z powodu numerów linii.