Jak VM przekształca kod
Obejrzyj
Obfuscator.io: Targeting Functions in VM Obfuscation (IIFE and Comment Mode)
Przy vmTargetFunctionsMode: 'root' (domyślnie) obfuskacja VM przekształca ciało każdej funkcji najwyższego poziomu (lub, przy vmAsyncExecutor, każdej najbardziej zewnętrznej funkcji async) w kod bajtowy. Funkcje najwyższego poziomu zachowują swoje nazwy; nazwy funkcji zagnieżdżonych są zmieniane jak zwykle. Aby zamiast tego wybierać pojedyncze funkcje na dowolnym poziomie zagnieżdżenia, użyj trybu komentarzy.
Takie rozwiązanie zapewnia zgodność z kodem, który wywołuje te funkcje z zakresu globalnego lub oczekuje ich w obiekcie globalnym. Ciało funkcji jest w pełni chronione, ale nazwa pozostaje widoczna, a obfuskator zgłasza ostrzeżenie VMGlobalFunctionNamesNotRenamed z listą takich nazw.
Obfuskacja VM chroni ciała funkcji, a także inicjalizatory zmiennych najwyższego poziomu, gdy włączona jest opcja vmWrapTopLevelInitializers (zobacz niżej). Jeśli kod wejściowy nie zawiera żadnej funkcji ani takiego inicjalizatora, czyli składa się wyłącznie z kodu najwyższego poziomu, takiego jak alert(1);, nic nie zostaje zwirtualizowane: pozostała część obfuskacji nadal jest wykonywana, ale ochrona VM nie jest stosowana, a obfuskator zgłasza ostrzeżenie VMNoFunctionsToVirtualize (v7.14.1+; sama wersja 7.14.0 jest wyłączona). Ostrzeżenie pojawia się także wtedy, gdy funkcje istnieją, ale każda z nich została pominięta (na przykład z powodu bezpośredniego eval lub dynamicznego new Function, gdy vmTargetFunctions/vmExcludeFunctions nie pozostawiają żadnej wybranej funkcji, albo gdy vmAsyncExecutor nie znalazł żadnej funkcji async). Umieść kod, który chcesz chronić, wewnątrz funkcji, na przykład IIFE.
Inicjalizatory najwyższego poziomu
W trybie root opcja vmWrapTopLevelInitializers opakowuje kwalifikujące się inicjalizatory zmiennych najwyższego poziomu, takie jak const MY_STRING = 'my-string';, w IIFE, dzięki czemu ich wartości trafiają do kodu bajtowego, zamiast pozostawać widoczne jako zwykły JavaScript. Obecne presety VM ją włączają. Obejmuje ona wyłącznie inicjalizatory zmiennych, a nie inne instrukcje najwyższego poziomu, i nie działa w trybie komentarzy. Inicjalizatory, które pozostają zwykłym JavaScriptem, są wymienione w ostrzeżeniu VMTopLevelInitializerNotVirtualized.
Ukrywanie wrażliwych nazw funkcji
Ponieważ tryb root zachowuje nazwę, zdradzająca nazwa, taka jak validateLicense czy decryptData, pozostaje czytelna nawet wtedy, gdy ciało funkcji staje się kodem bajtowym. Rozwiązaniem jest przeniesienie funkcji z najwyższego poziomu - opakowanie jej w IIFE, gdzie nie jest już funkcją poziomu głównego i zostaje w pełni przekształcona przez VM, łącznie z nazwą - albo zmiana nazw identyfikatorów najwyższego poziomu za pomocą renameGlobals. Obie techniki wraz z ich kompromisami opisuje przewodnik Ukrywanie nazw funkcji przed analizą LLM.
