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
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.
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).
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.
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.
- 1. HashMap.this.clear() co to znaczy, jak to działa
- 2. co to jest [cmdletbinding()] i jak to działa?
- 3. Co to jest mangling nazw i jak to działa?
- 4. Co to jest VertiPaq i jak działa
- 5. Co to jest "usuń to"?
- 6. Co to jest Serializable? Co to znaczy?
- 7. Co to jest plik IOR, co robi i jak działa?
- 8. Co to jest NuGetPackageImportStamp?
- 9. Co to jest hyperkube?
- 10. Co to jest []
- 11. co to jest alloc.h?
- 12. Co to jest StackOverflowError?
- 13. Co to jest ZuckMail?
- 14. Co to jest "vendoring"?
- 15. Co to jest? rodzaj?
- 16. Co to jest _GLOBAL_OFFSET_TABLE?
- 17. Co to jest czasownik = "*"?
- 18. Co to jest NSEraCalendarUnit?
- 19. Co to jest ActionDispatch?
- 20. Co to jest DetailsView.EnableModelValidation?
- 21. Co to jest $ {project.licensePath}?
- 22. Co to jest ws: //?
- 23. Co to jest kontekst?
- 24. Co to jest CHAR_BIT?
- 25. Co to jest Routedata.Values [""]?
- 26. Co to jest __meteor_bootstrap__?
- 27. Co to jest project.lock.json?
- 28. nie ma towarzyszącego wiązania - co to znaczy? Jak to działa?
- 29. Co to jest IllegalStateException?
- 30. Co to jest HMODULE?
Jaka jest ogólna zasada, która kryje się za jednym? –
W rzeczywistości często można uzyskać nazwy zmiennych dla języka Java i pliki GCC gotowe do pracy z debugowaniem. – paxdiablo
@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ł. :) –