2014-04-24 15 views
5

Myślę o manipulowaniu kodami bajtowymi (myślę o programowaniu genetycznym) w Pythonie.Jak sprawdzić kod bajtowy Pythona?

natknąłem przypadku testowego w crashers test section drzewa źródłowego Pythona, który stwierdza:

Broken bytecode objects can easily crash the interpreter. This is not going to be fixed.

zatem pytanie, w jaki sposób sprawdzić poprawność podane manipulowane kodu bajtowego, że to nie będzie katastrofy tłumacza? Czy to możliwe?

źródło Test, po http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html

cc = (lambda fc=(
    lambda n: [ 
     c for c in 
      ().__class__.__bases__[0].__subclasses__() 
      if c.__name__ == n 
     ][0] 
    ): 
    fc("function")(
     fc("code")(
      0, 0, 0, 0, "KABOOM",(),(),(), "", "", 0, "" 
     ), {} 
    )() 
) 

tutaj, to moduł definiuje cc że jeśli nazywa, mymod.cc() awarii tłumacza. Jest to bardzo podstępny przykład, który utworzył nowy obiekt kodu z niestandardowym bajtowym kodem "KABOOM", a następnie uruchamia go.

Przyjmę coś, co weryfikuje predefiniowany kod bajtowy, np. z pliku .pyc.

+4

Nie znam żadnej metody potwierdzającej kod bajtowy, nie. To trudne zadanie; lepiej po prostu wydaj prawidłowy kod bajtowy. –

+2

Myślę, że może to być nierozstrzygalne. Załóżmy, że masz kod bajtowy równoważny: 'if method_that_may_loop_forever(): crash()'. musiałbyś rozwiązać [problem z zatrzymaniem] (http://en.wikipedia.org/wiki/Halting_problem), aby ustalić, czy ulegnie awarii, czy nie. – Kevin

+3

@Kevin Z pewnością nie chcę rozwiązać problemu z zatrzymaniem. Chcę tylko określić, czy dana sekwencja kodu bajtowego jest gwarantowana jako bezpieczna lub potencjalnie niebezpieczna. Podobne do tego, co robi JVM. –

Odpowiedz

1

Zarówno przestarzały, pierwszy bez kodu (przynajmniej ja nie mogę znaleźć), ale może być przydatna, aby dać wyobrażenie o tym, co/jak można zrobić i jakie są ograniczenia.

perfectly valid bytecode can still do horrible things

+0

Przynajmniej dla prostego '' KABOOM "' jest zauważone przez 'Python-Bytecode-Verifier' z' verifier.VerificationError: Unverifiable code: Stack underflow. Odsunięcie: 0 Stos: 0 Granica: 0 Wymagane: 2'; oczywiście pakiet jest beznadziejnie przestarzały. –

1

Python może nie być idealnym językiem do takich zadań, z przyczyn określonych w pytaniu.

Jedna metoda: Nie twórz ani nie akceptuj kodu bajtowego, akceptuj tylko kod źródłowy Pythona i sam je kompiluj.

Ponadto istnieją biblioteki (RestrictedPython), które manipulują Pythonem na poziomie AST, aby uzyskać pewne gwarancje bezpieczeństwa, np. aby uniknąć ucieczki piaskownicy.

+0

Proszę mnie poprawić, jeśli się mylę, ale 'RestrictedPython' wymaga źródła Pythona jako wejścia, prawda? –

+0

Tak. To jest AST - abstrakcyjne drzewo składniowe. Jeśli chcesz być pedantyczny, to nie jest to kod źródłowy. Tak więc, zrzeczenie się odpowiedzialności (może nie odpowiadać twojemu podejściu). –

3

Używanie kodu bajtowego Assembler wykonuje śledzenie stosów przez skoki, globalnie weryfikuje spójność prognozowania poziomu stosu i automatycznie odrzuca próby wygenerowania martwego kodu. Jest praktycznie niemożliwe, aby przypadkowo wygenerować kod bajtowy, który może spowodować awarię interpretera.

Ta Link może ci pomóc.

+1

Dobra biblioteka/link, muszę zweryfikować, czy rzeczywiście sprawdza kod bajtowy w żądanym stopniu. Podejrzewam, że walidacja skoków dowolnych kodów jest technicznie nierozstrzygalna, dlatego pytanie brzmi, czy asembler kodu bajtowego błądzi po stronie ostrożności (odrzuca potencjalnie zły kod bajtowy) lub po stronie użytkownika (umożliwia potencjalnie dobry kod). –

+0

jeśli używasz modułu BytecodeAssembler (http://pypi.python.org/pypi/BytecodeAssembler), nie będziesz musiał wymyślać tych rzeczy. W związku z tym ma wiele wsparcia dla etykiet, obsługi bloków itp. Pełna instrukcja znajduje się na stronie (http://peak.telecommunity.com/DevCenter/BytecodeAssembler) – devst3r

+1

Obawiam się, że to oświadczenie dotyczy tylko generowania kod przy użyciu 'BytecodeAssembler', a nie podczas analizowania istniejącego kodu bajtowego. Może okazać się możliwe mapowanie istniejącego kodu bajtowego na sekwencje wywołań API, ale próbuję coś zhakować ... –

Powiązane problemy