Panta rheiããããŠæŽæ°ãããã³ãŒã¹ãPython Web Developerãã®ç«ã¡äžããè¿ã¥ããŠããŸãããç§ãã¡ã¯éåžžã«èå³æ·±ããããªããšå ±æãããè³æããŸã æã£ãŠããŸãã
ãªã挬ç©ãå±éºãªã®ã§ããïŒ
ãããã®æŒ¬ç©ã¯éåžžã«å±éºã§ãã ã©ã®ããã«èª¬æããã®ãããåãããŸããã ãã ä¿¡ããŠã ããã¯éèŠã§ãããïŒãççºæ§é害ããã³ãã©ã¬
ãªãã³ãŒãã«é£ã³èŸŒãåã«ãåºæ¬ã«ã€ããŠè©±ããŸãããã Pythonæšæºã©ã€ãã©ãªã«ã¯ããªããžã§ã¯ããã·ãªã¢ã«åããã³éã·ãªã¢ã«åããããã«äœ¿çšãããpickle ïŒã pickle ããŸãã¯åã«ãä¿åããšç¿»èš³ãããïŒãšåŒã°ããã¢ãžã¥ãŒã«ããããŸãã ããã®ã¿ããã·ãªã¢ã©ã€ãŒãŒã·ã§ã³/ãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ã§ã¯ãªãããã¯ã«ã¹å/ã¢ã³ãã¯ã«ã¹åãšåŒã°ããŸãïŒæåéã-ãä¿å/ä¿å解é€ãïŒã
C ++ã§Boost Serializationã䜿çšããåŸãæªå€¢ã«èŠããã§ãã人ãšããŠãç§ã¯ä¿åãåªããŠãããšèšãããšãã§ããŸãã ããªãã圌女ã«äœãæããŠãã圌女ã¯ãã ä»äºãç¶ããŸãã ãŸããçµã¿èŸŒã¿åã ãã§ãªããã»ãšãã©ã®å Žåãã·ãªã¢ã«åãã£ãã³ã°ã¡ãœãããèšè¿°ããå¿ èŠãªããã¯ã©ã¹ãã·ãªã¢ã«åã§ããŸãã ååž°çãªããŒã¿æ§é ãªã©ã®ãªããžã§ã¯ãïŒåæ§ã®ããŒã·ã£ãªã³ã°ã¢ãžã¥ãŒã«ã䜿çšãããšã¯ã©ãã·ã¥ãåŒãèµ·ããïŒã§ããåé¡ã¯ãããŸããã
以äžã¯ãpickleã¢ãžã¥ãŒã«ã«æ £ããŠããªã人ã®ããã®ç°¡åãªäŸã§ãã
import pickle # Python original = { 'a': 0, 'b': [1, 2, 3] } # pickled = pickle.dumps(original) # identical = pickle.loads(pickled)
ã»ãšãã©ã®å Žåãããã§ååã§ãã ä¿åã¯æ¬åœã«ã¯ãŒã«ã§ã...ããããæ·±ã¿ã®ã©ããã«æéãé ãããŠããŸãã
pickleã¢ãžã¥ãŒã«ã®æåã®è¡ã®1ã€ã¯ããèšããŸãïŒ
泚æïŒpickleã¢ãžã¥ãŒã«ã¯ã誀ã£ãããŒã¿ãæªæã®ããããŒã¿ããä¿è·ãããŠããŸããã ä¿¡é Œã§ããªããèš±å¯ãããŠããªããœãŒã¹ããã®ããŒã¿ãåä¿åããªãã§ãã ããã
ç§ã¯ãã®èŠåãäœåºŠãèªã¿ãŸããããæªæã®ããããŒã¿ãäœã§ããããšããçåã«æããŸããã ãããŠæè¿ãç§ã¯ãããèŠã€ããæã ãšæ±ºããŸããã ç¡é§ã§ã¯ãããŸããã
æªæã®ããããŒã¿ãäœæããããã®æ¢æ±ã¯ãpickleãããã³ã«ã«ã€ããŠå€ããåŠã³ãä¿åããããã°ããããã®ã¯ãŒã«ãªæ¹æ³ãçºèŠããPythonãœãŒã¹ã³ãŒãã§å€§èãªã³ã¡ã³ããããã€ãèŠã€ããŸããã èªã¿ç¶ãããšãåãå©ç¹ãåŸãããŸãïŒãããŠããã«ãæªæã®ããä¿è·ãã¡ã€ã«ãéä¿¡ãå§ããã§ãããïŒã èŠåïŒæè¡çãªè©³çŽ°ããããŸãããå¯äžã®åææ¡ä»¶ã¯Pythonã®åºæ¬çãªç¥èã§ãã ããããã¢ã»ã³ãã©ã®è¡šé¢çãªç¥èã¯å®³ã«ãªããŸããã
åœã®ãã¯ã«ã¹ç匟
ç§ã¯pickleã¢ãžã¥ãŒã«ã®ããã¥ã¡ã³ããèªãããšããå§ãããšãªãŒãããã«ãŒã«ãªãããã®ãã³ããèŠã€ããããšæã£ãŠã次ã®ãããªè¡ã«åºäŒããŸããã
pickletoolsã¢ãžã¥ãŒã«ã«ã¯ãä¿åã«ãã£ãŠçæãããããŒã¿ãããŒãåæããããã®ããŒã«ãå«ãŸããŠããŸãã pickletoolsã®ãœãŒã¹ã³ãŒãã«ã¯ãpickleãããã³ã«ã§äœ¿çšããããªãã³ãŒãã«é¢ããåºç¯ãªã³ã¡ã³ããå«ãŸããŠããŸãã
ãªãã³ãŒãïŒ pickleã®å®è£ ã次ã®ããã«ãªããšã¯æã£ãŠããŸããã§ããã
def dumps(obj): return obj.__repr__() def loads(pickled): # : pickle ... return eval(pickled)
ããããç§ã¯åœŒå¥³ã圌女èªèº«ã®äœã¬ãã«èšèªãå®çŸ©ããããšãæåŸ ããŠããŸããã§ããã 幞ããªããšã«ãè¡ã®2çªç®ã®éšåã¯çå®ã瀺ããŠããŸã-pickletoolsã¢ãžã¥ãŒã«ã¯ããããã³ã«ãã©ã®ããã«æ©èœããããç解ããã®ã«éåžžã«åœ¹ç«ã¡ãŸãã ããã«ãã³ãŒãå ã®ã³ã¡ã³ãã¯éåžžã«é¢çœãããšãããããŸããã
ããšãã°ãçŠç¹ãåœãŠãå¿ èŠããããããã³ã«ã®ããŒãžã§ã³ã®åé¡ãæèµ·ããŸãã Python 3.6ã«ã¯åèš5ã€ãããŸãã ãããã¯0ãã4ãŸã§ã®çªå·ãä»ããããŠããŸãããããã³ã«0ã¯ãããã¥ã¡ã³ãã§ã èªã¿åãå¯èœ ããšåŒã°ãã pickletoolsãœãŒã¹ã³ãŒããè¿œå æ å ±ãæäŸãããããæãããªéžæã§ãã
ãã¯ã«ãªãã³ãŒãã¯ãç©äºã®æ°ããæ¹æ³ãç»å ŽããŠããã§ãŒãããããšã¯ãããŸããã PMã®ã¬ããŒããªãŒã¯æéãšãšãã«æé·ããŠããŸã...ãOpscode bloatingãã¯åŸ®åŠãªãã³ãã§ã¯ãªãã衰匱ãããå°é£ã®åå ã§ãã
æ°ãããããã³ã«ã¯ãããããåã®ãããã³ã«ã®ã¹ãŒããŒã»ããã§ããããšãããããŸããã ãããã³ã«0ããèªã¿åãå¯èœãã§ããããšãèæ ®ããªããŠãïŒåœä»€ãéã³ã³ãã€ã«ããããåé¡ã§ã¯ãããŸããïŒãå¯èœãªéãå°ãªããªãã³ãŒããå«ãŸããŠããŸãã æªæã®ããpickleãã¡ã€ã«ãã©ã®ããã«äœæãããããç解ããããšãç®æšã§ããå Žåãããã¯çæ³çã§ãã
ãªãã³ãŒããšæ··åããŠãå¿é ããå¿ èŠã¯ãããŸããã ããã§Pythonã«æ»ãããªãã³ãŒããPythonã³ãŒãã«ã©ã®ããã«é¢é£ãããã詳ãã説æããŸãã ãªãã³ãŒãã®ãªãåçŽãªPythonã¯ã©ã¹ãäœæããŸãã
class Bomb: def __init__(self, name): self.name = name def __getstate__(self): return self.name def __setstate__(self, state): self.name = state print(f'Bang! From, {self.name}.') bomb = Bomb('Evan')
__setstate __ïŒïŒããã³__getstate __ïŒïŒã¡ãœããã¯ãã¯ã©ã¹ãã·ãªã¢ã©ã€ãºããã³ãã·ãªã¢ã©ã€ãºããããã«pickleã¢ãžã¥ãŒã«ã§äœ¿çšãããŸãã ããã©ã«ãã®å®è£ ã¯__dict__ã€ã³ã¹ã¿ã³ã¹ãåçŽã«ã·ãªã¢ã«åããã ããªã®ã§ãå€ãã®å Žåãèªåã§å®çŸ©ããå¿ èŠã¯ãããŸããã ã芧ã®ãšãããBombãªããžã§ã¯ãã®ãã·ãªã¢ã©ã€ãºã®ç¬éã«ã¡ãã£ãšããé©ããé ãããã«ãããã§çŽæ¥å®çŸ©ããŸããã
éã·ãªã¢ã«åã³ãŒããåäœãããã©ããã確èªããŠãã ããã 以äžã䜿çšããŠããªããžã§ã¯ããä¿åããã³åä¿åã§ããŸãã
import pickle pickled_bomb = pickle.dumps(bomb, protocol=0) unpickled_bomb = pickle.loads(pickled_bomb)
ååŸãããã®ïŒ
# -! . Bang! From, Evan.
ãŸãã«èšç»éãïŒ å¯äžã®åé¡ããããŸããBombãå®çŸ©ãããŠããªãã³ã³ããã¹ãã§pickled_bompè¡ãéã·ãªã¢ã«åããããšããŠããäœãæ©èœããŸããã 代ããã«ããšã©ãŒã衚瀺ãããŸãã
AttributeError: Can't get attribute 'Bomb' on <module '__main__'>
__setstate__()
çãªã³ã³ããã¹ããæªæã®ããå°å·åŒã䜿çšããŠã³ãŒãã«æ¢ã«ã¢ã¯ã»ã¹ããŠããå Žåã«ã®ã¿ãã«ã¹ã¿ã ã¡ãœãã
__setstate__()
å®è¡ã§ããããšã
__setstate__()
ãŸãã ãããŠã被害è ãç«ã¡äžããã³ãŒãã«ãã§ã«ã¢ã¯ã»ã¹ã§ããã®ã«ããªããã¯ã«ã¹ã§æ©ãã®ã§ããïŒ è¢«å®³è ã䜿çšããä»ã®æ¹æ³ã§æªæã®ããã³ãŒããç°¡åã«æžãããšãã§ããŸãã ããã¯æ¬åœã§ã-ç§ã¯ãããå®èšŒãããã£ãã ãã§ãã
çµå±ãPytonããªããžã§ã¯ãã®éã·ãªã¢ã«åã¡ãœããã®ä¿åãã€ãã³ãŒãããµããŒãããŠããã®ã§ã¯ãªãããšçãããšã¯ç¡é§ã§ã¯ãããŸããã ããšãã°ãããŒã·ã£ã«ã¢ãžã¥ãŒã«ã¯ã¡ãœãããã·ãªã¢ã«åã§ããå€ãã®pickleã®ä»£æ¿ææ®µïŒ marshmallow ã dill ãããã³pyroãé¢æ°ã®ã·ãªã¢ã«åããµããŒãããŠããŸãã
ãã ããpickleã®ããã¥ã¡ã³ãã«ããäžåãªèŠåã¯ããããæå³ãããã®ã§ã¯ãããŸããã éã·ãªã¢ã«åã®å±éºæ§ã調ã¹ãã«ã¯ãããå°ãæ·±ãæãäžããå¿ èŠããããŸãã
Pickleã®éã³ã³ãã€ã«
ä¿å šãå®éã«ã©ã®ããã«æ©èœããããç解ããããšããæã§ãã åã®ã»ã¯ã·ã§ã³ã®ãªããžã§ã¯ãpickled_bombãèŠãŠã¿ãŸãããã
b'ccopy_reg\n_reconstructor\np0\n(c__main__\nBomb\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\nVEvan\np5\nb.'
åŸ ã£ãŠãã ãã...ãããã³ã«0ã䜿çšããŸãããïŒ ãèªã¿åãå¯èœãã§ããïŒ
ããããããã¯åé¡ãããŸãããpickletoolsã®ãœãŒã¹ã³ãŒãã«ã¯ã ãpickleãããã³ã«ã§äœ¿çšããããªãã³ãŒãã«é¢ããåºç¯ãªã³ã¡ã³ããããããŸãã åé¡ã解決ããã®ã«åœ¹ç«ã€ã¯ãã§ãïŒ
ç§ã¯ããã詳现ã«ææžåããããšãåæããŠããŸã-ãã¹ãŠã®ç¹å¥ãªã±ãŒã¹ãèŠã€ããããã«ãã¯ã«ã¹ã³ãŒããå®å šã«èªãã§ãã ããã-pickletoolsãœãŒã¹ã³ãŒãã®ã³ã¡ã³ã
ãªããŠãã£ã äœã«é©åããŸããïŒ
åè«ã§ãããpickleããŒã«ã®ãœãŒã¹ã³ãŒãã¯æ¬åœã«çŽ æŽãããã³ã¡ã³ãã§ãã ãŸããããŒã«èªäœãåæ§ã«æçšã§ãã ããšãã°ãpickletools.disïŒïŒãšããpickleãå解ããã¡ãœããããããŸãã ãã¯ã«ã¹ãããç解ããããèšèªã«ç¿»èš³ããã®ã«åœ¹ç«ã¡ãŸãã
pickled_bombè¡ãéã¢ã»ã³ãã«ããã«ã¯ã次ãå®è¡ããŸãã
import pickletools pickletools.dis(pickled_bomb)
: 0: c GLOBAL 'copy_reg _reconstructor' 25: p PUT 0 28: ( MARK 29: c GLOBAL '__main__ Bomb' 44: p PUT 1 47: c GLOBAL '__builtin__ object' 67: p PUT 2 70: N NONE 71: t TUPLE (MARK at 28) 72: p PUT 3 75: R REDUCE 76: p PUT 4 79: V UNICODE 'Evan' 85: p PUT 5 88: b BUILD 89: . STOP highest protocol among opcodes = 0
x86 ã Dalvik ã CLRãªã©ã®èšèªãæ±ã£ãŠããå Žåãäžèšã®ãã¹ãŠãããªãã¿ã®ããã«æãããããããŸããã ãããã圌ãããããæã£ãŠããªãã£ããšããŠã-ããã¯åé¡ã§ã¯ãããŸããããç§ãã¡ã¯æ®µéçã«ãããåããŸãã çŸæç¹ã§ã¯ãGLOBALãPUTãããã³MARKãªã©ã®èŠåºãèªã¯ãé«æ°Žæºèšèªã®é¢æ°ã®ããã«ã»ãšãã©è§£éããããªãã³ãŒãããã³åœä»€ã§ããããšãç¥ãã ãã§ååã§ãã å³åŽã¯ãã¹ãŠãããã®é¢æ°ã®åŒæ°ã§ãããå·ŠåŽã¯å ã®ãèªã¿åãå¯èœãªãè¡ã§ã®æå·åæ¹æ³ã瀺ããŠããŸãã
ãã ãããŠã©ãŒã¯ã¹ã«ãŒãéå§ããåã«ãpickletoolsããå¥ã®äŸ¿å©ãªãã®ã玹ä»ããŸãããïŒpickletools.optimizeïŒïŒã ãã®ã¡ãœããã¯ãæªäœ¿çšã®ãªãã³ãŒãããã¯ã«ã¹ããåé€ããŸãã åºåã¯åçŽåãããŠããŸãããåæ§ã®ãã¯ã«ã¹ã§ãã 次ãå®è¡ããããšã«ãããpickled_bombã®æé©åãããããŒãžã§ã³ã解æã§ããŸãã
pickled_bomb = pickletools.optimize(pickled_bomb) pickletools.dis(pickled_bomb)
ãããŠãäžé£ã®æ瀺ã®ç°¡ç¥çãååŸããŸãã
0: c GLOBAL 'copy_reg _reconstructor' 25: ( MARK 26: c GLOBAL '__main__ Bomb' 41: c GLOBAL '__builtin__ object' 61: N NONE 62: t TUPLE (MARK at 25) 63: R REDUCE 64: V UNICODE 'Evan' 70: b BUILD 71: . STOP highest protocol among opcodes = 0
ããã¯ããã¹ãŠã®PUTãªãã³ãŒããååšããªãå Žåã«ã®ã¿ãªãªãžãã«ãšç°ãªãããšã«æ°ä»ããããããŸããã ããã«ãããç解ããããã®10ã®æé ãæ®ããŸãã ããã«ããããåå¥ã«æ€èšããPythonã³ãŒããæåã§ã解æãããŸãã
ä¿åäžããªãã³ãŒãã¯éåžžPickle MachineïŒPMïŒãšåŒã°ãããšã³ãã£ãã£ã«ãã£ãŠè§£éãããŸãã åãã¯ã«ã¯ãã³ã³ãã€ã«ãããJavaã³ãŒããJavaä»®æ³ãã·ã³ïŒJVMïŒã§å®è¡ãããã®ãšåæ§ã«ãPMã§å®è¡ãããããã°ã©ã ã§ãã pickleã³ãŒãã解æããã«ã¯ãPMã®åäœãç解ããå¿ èŠããããŸãã
PMã«ã¯ãããŒã¿ãä¿åããããããšããåãããããã®2ã€ã®é åããããŸããã¡ã¢ãšã¹ã¿ãã¯ã§ãã ã¡ã¢ã¯ãé·æä¿åçšã«èšèšãããŠãããæŽæ°ãšãªããžã§ã¯ããæ¯èŒããPythonèŸæžã«äŒŒãŠããŸãã ã¹ã¿ãã¯ã¯ãå€ãã®æäœãçžäºäœçšããç©ãè¿œå ãããåŒãåºãããããPythonãªã¹ãã®ãããªãã®ã§ãã ãããã®PythonããŒã¿é åã次ã®ããã«ãšãã¥ã¬ãŒãã§ããŸãã
# / PM memo = {} # Stack PM, stack = []
ä¿åäžãPMã¯pickleããã°ã©ã ãèªã¿åããååœä»€ãé 次å®è¡ããŸãã STOPãªãã³ãŒãã«å°éãããã³ã«çµäºããŸãã ã¹ã¿ãã¯ã®äžçªäžã«ãããªããžã§ã¯ãã¯ãåä¿åã®æçµçµæã§ãã ãšãã¥ã¬ãŒããããã¡ã¢ãšã¹ã¿ãã¯ãªããžããªã䜿çšããŠããã¯ã«ã¹ãPythonã«åœä»€ããšã«å€æããŠã¿ãŸãããã
- GLOBALã¯ãã¯ã©ã¹ãšé¢æ°ãã¹ã¿ãã¯ã«ããã·ã¥ããã¢ãžã¥ãŒã«ãšååãåŒæ°ãšããŠæž¡ããŸãã Python 3ã§ã¯copy_regã®ååãcopyregã«å€æŽããããããã¡ãã»ãŒãžã¯å°ã誀解ãæãããšã«æ³šæããŠãã ããã
- MARKã¯ç¹å¥ãªmarkobjectãã¹ã¿ãã¯ã«ããã·ã¥ãããããåŸã§ããã䜿çšããŠã¹ã¿ãã¯ã®äžéšãæå®ã§ããŸãã æååãMARKãã䜿çšããŠãããŒã¯ãªããžã§ã¯ããè¡šããŸãã
# markobject . # 25: ( MARK stack.append('MARK')
- åã³ã°ããŒãã« ã ãã ããä»åã¯__main__ã¢ãžã¥ãŒã«ã䜿çšãããããã€ã³ããŒãããå¿
èŠã¯ãããŸããã
# (module.attr) . # 26: c GLOBAL '__main__ Bomb' stack.append(Bomb)
- åã³ã°ããŒãã« ã ãŸãããªããžã§ã¯ããæ瀺çã«ã€ã³ããŒãããå¿
èŠã¯ãããŸããã
# (module.attr) . # 41: c GLOBAL '__builtin__ object' stack.append(object)
- NONEã¯ãNoneãã¹ã¿ãã¯ã«ããã·ã¥ããã ãã§ãã
# None . # 61: N NONE stack.append(None)
- TUPLEã¯å°ãè€éã§ãã ã¹ã¿ãã¯ã«ãMARKããè¿œå ããæ¹æ³ãèŠããŠããŸããïŒ ãã®æäœã¯ããMARKãã®åŸã®ã¹ã¿ãã¯ããã¿ãã«ã«ãã¹ãŠã移åããŸãã ãã®åŸã圌女ã¯ãMARKããåé€ããã¿ãã«ã«çœ®ãæããŸãã
# , markobject. # 62: t TUPLE (MARK at 28) last_mark_index = len(stack) - 1 - stack[::-1].index('MARK') mark_tuple = tuple(stack[last_mark_index + 1:]) stack = stack[:last_mark_index] + [mark_tuple] , . # TUPLE: [<function copyreg._reconstructor>, 'MARK', __main__.Bomb, object, None] # TUPLE: [<function copyreg._reconstructor>, (__main__.Bomb, object, None)]
- REDUCEã¯ãã¹ã¿ãã¯ããæåŸã®2ã€ã®ãã®ãåé€ããŸãã ãã®åŸãæåŸã®ãªããžã§ã¯ãã®äœçœ®æ¡åŒµã䜿çšããŠæåŸãã2çªç®ã®ãªããžã§ã¯ããåŒã³åºããçµæãã¹ã¿ãã¯ã«é
眮ããŸãã èšèã§èª¬æããã®ã¯é£ããã§ãããã³ãŒãã§ã¯ãã¹ãŠãæ確ã§ã
# , callable tuple . # 63: R REDUCE args = stack.pop() callable = stack.pop() stack.append(callable(*args))
- UNICODEã¯Unicodeæååãã¹ã¿ãã¯ã«ããã·ã¥ããã ãã§ãïŒã¡ãªã¿ã«ãéåžžã«åªããUnicodeæååã§ãïŒïŒ
# Python Unicode. # 64: V UNICODE 'Evan' stack.append(u'Evan')
- BUILDã¯ãã¹ã¿ãã¯ããæåŸã®ãªããžã§ã¯ããåé€ãããããåŒæ°ãšããŠ__setstate __ïŒïŒã«ã¹ã¿ãã¯ã®æ°ããæåŸã®ãã®ãšãšãã«æž¡ããŸã
# __setstate__ dict. # 70: b BUILD arg = stack.pop() stack[-1].__setstate__(arg)
- STOPãšã¯ãåã«ã¹ã¿ãã¯ã®äžçªäžã®ã¢ã€ãã ãæçµçµæã§ããããšãæå³ããŸãã
# PM. # 71: . STOP unpickled_bomb = stack[-1]
ãµããå®äºã§ãïŒ ã³ãŒããç¹ã«Pythonã§ãããã©ããã¯ããããŸããããPMããšãã¥ã¬ãŒãããŸãã ã¡ã¢ã䜿çšããããšããªãããšã«æ°ä»ããããããŸããã pickletools.optimizeïŒïŒã§åé€ããããã¹ãŠã®PUTãªãã³ãŒããèŠããŠããŸããïŒ åœŒãã¯ã¢ã¢ãšããåãããŠãããããããŸããããç°¡åãªäŸã§ã¯ããã¯å¿ èŠãããŸããã§ããã
ã³ãŒããåçŽåããŠããã®äœæ¥ãæ確ã«ç€ºããŸãããã å®éãããŒã¿ã®ã·ã£ããã«ã«å ããŠãåœä»€1ã§_reconstructorãã€ã³ããŒãããåœä»€7ã§_reconstructorãåŒã³åºããåœä»€9ã§__setstate __ïŒïŒãåŒã³åºããšãã3ã€ã®æäœã®ã¿ãçºçããŸããããŒã¿ã®ã·ã£ããã«ãæ³åãããšãPythonã®3è¡ãã¹ãŠãè¡šçŸã§ããŸãã
# 1, `_reconstructor` from copyreg import _reconstructor # 7, `_reconstructor` unpickled_bomb = _reconstructor(cls=Bomb, base=object, state=None) # 9, `__setstate__` unpickled_bomb.__setstate__('Evan')
copyreg._reconstructorïŒïŒãœãŒã¹ã³ãŒãã®å éšãèŠããšãåã«ãªããžã§ã¯ã.__ new __ïŒBombïŒãåŒã³åºããŠããããšãããããŸãã ãã®ç¥èã䜿çšããŠããã¹ãŠã2è¡ã«ç°¡ç¥åã§ããŸãã
unpickled_bomb = object.__new__(Bomb) unpickled_bomb.__setstate__('Evan')
ããã§ãšãããããŸããããªãã¯ãã¯ã«ã¹ãéã³ã³ãã€ã«ããŸããïŒ
ãªã¢ã«ãã¯ã«ãã
ç§ã¯ãã¯ã«ã¹ã®å°é家ã§ã¯ãããŸããããæªæã®ãããã¯ã«ã¹ã®äœææ¹æ³ã«ã€ããŠã¯ãã§ã«èª¬æã§ããŸãã GLOBALãªãã³ãŒãã䜿çšããŠä»»æã®é¢æ°ïŒos.systemããã³__builtin __ïŒãã€ã³ããŒãã§ããŸããEvalã¯é©åãªåè£ã®ããã§ãã ãããŠãREDUCEã䜿çšããŠãä»»æã®åŒæ°ã§å®è¡ããŸãã ãããããã ...åŸ ã£ãŠãããã¯äœã§ããïŒ
isinstanceïŒcallableãtypeïŒã§ãªãå Žåãcallregableãcopyregã¢ãžã¥ãŒã«ã®safe_constructorsãã£ã¯ã·ã§ããªã«ç»é²ãããŠããå ŽåããŸãã¯callableã«trueå€ãæã€ããžãã¯ã¢ããªãã¥ãŒã__safe_for_unpickling__ãããå Žåã«ã®ã¿ãREDUCEã¯å®£èªããŸããã ãªããããèµ·ããã®ãã¯ããããŸãããã<winks>ãšããäžæºã¯ååã«ãããŸãã
å¿çããŠãŠã£ã³ã¯ã pickletoolsã®ããã¥ã¡ã³ãã¯ãèš±å¯ãããcallableã®ã¿ãREDUCEã§å®è¡ã§ããããšã瀺åããŠããããã§ãã ãã°ããã®éãç§ã¯å¿é ããŸãããããsafe_constuctorsããæ€çŽ¢ãããšã2003幎ããPEP 307ãããã«èŠã€ãããŸããã
Pythonã®ä»¥åã®ããŒãžã§ã³ã§ã¯ãä¿å解é€ã«ã¯åã ã®æäœã«å¯Ÿãããã»ãã¥ãªãã£ãã§ãã¯ããããã__ safe_for_unpickling__å±æ§ã1ã«çãããããŸãã¯ã°ããŒãã«ã¬ãžã¹ã¿copy_reg.safe_constructorsã«ç»é²ããããã«ãä¿å解é€ããšããŒã¯ãããŠããªãé¢æ°ãŸãã¯ã³ã³ã¹ãã©ã¯ã¿ãŒã®åŒã³åºããæåŠããŸããã
ãã®é¢æ°ã¯ã誀ã£ãå®å¿æãçã¿åºããŸããä¿¡é Œã§ããªããœãŒã¹ããã®ãã¯ã«ã¹ã®éžæãäžèŠãªã³ãŒããåŒãèµ·ãããªãããšã蚌æããããã«å¿ èŠãªåºç¯ãªã³ãŒãæ€èšŒãå®è¡ãã人ã¯ããŸããã å®éãPython 2.2ã®pickle.pyã¢ãžã¥ãŒã«ã®ãã°ã«ããããããã®äºé²æªçœ®ãç°¡åã«åé¿ã§ããŸãã
ã€ã³ã¿ãŒãããã䜿çšããå Žåãå®è£ ãå®å šã«æ€èšŒãããŠããªããããã³ã«ã®ã»ãã¥ãªãã£ãä¿¡é Œãããããããããã³ã«ãå®å šã§ãªãããšãç¥ã£ãæ¹ããããšåºãä¿¡ããŠããŸãã äžè¬çãªãããã³ã«ã®é«å質ã®å®è£ ã§ãããå€ãã®å Žåãšã©ãŒãå«ãã§ããŸãã å€ãã®æéããªããšãPythonã®pickleå®è£ ã¯ä¿èšŒã§ããŸããã ãããã£ãŠãPython 2.3以éããã¹ãŠã®ä¿å解é€ã»ãã¥ãªãã£ãã§ãã¯ã¯å ¬åŒã«é€å€ãããèŠåã«çœ®ãæããããŸãã
èŠå ïŒä¿¡é Œæ§ã®äœãæªæ€èšŒã®ãœãŒã¹ããã®ããŒã¿ãå床éããªãã§ãã ããã
ããã«ã¡ã¯ãæéãæ§å ã ããããã¹ãŠã®å§ãŸãã§ãã
ããããã¹ãŠã§ãããéèŠãªèŠçŽ ãèŠã€ããŸããããããŠãç§ãã¡ãããããšããŠããããšãã誀ã£ãå®å¿æã¯ãããŸããã§ããã ç匟ãæžãããšããå§ããŸãããïŒ
# arbitrary python GLOBAL '__builtin__ eval' # MARK # Python, UNICODE 'print("Bang! From, Evan.")' # , REDUCE TUPLE # `eval()` Python REDUCE # STOP, PM STOP
ãããå®éã®ãã¯ã«ã¹ã«ããã«ã¯ãåãªãã³ãŒãã察å¿ããASCIIã³ãŒãã«çœ®ãæããå¿ èŠããããŸãïŒGLOBALã®cãïŒMARKã®VãUNICODEã®VãTUPLEã®tãREDUCEã®Rãããã³STOPã®å Žåããããã¯åãå€ã§ããããšã«æ³šæããŠãã ããã pickletools.disïŒïŒã®åºåã®ãªãã³ãŒãã®å·ŠåŽã«æžã蟌ãŸããåŒæ°ã¯ãäœçœ®ãšæ¹è¡å¶çŽã®çµã¿åãããèæ ®ããŠåãªãã³ãŒãã®åŸã«ââåæãããŸããååŒæ°ã¯ã察å¿ãããªãã³ãŒãã®çŽåŸãŸãã¯åã®åŒæ°ã®åŸã«é 眮ãããæ¹è¡æåãèŠã€ãããŸã§ã 次ã®ããã«ç®ã®æŒ¬ç©ã³ãŒããçšæãããŠããŸãã
c__builtin__ eval (Vprint("Bang! From, Evan.") tR.
æåŸã«ãããã確èªã§ããŸãã
# ! # , ! pickled_bomb = b'c__builtin__\neval\n(Vprint("Bang! From, Evan.")\ntR.' pickle.loads(pickled_bomb)
III ...
# -! . Bang! From, Evan.
ããªãã¯ç§ãä¿¡ããçç±ããªãããšãç¥ã£ãŠããŸãããæ¬åœã«ããŸããããŸããã
誰ããevalïŒïŒã«å¯ŸããŠããæªæã®ããè°è«ãç°¡åã«æãä»ãããšãã§ããããšã¯ç°¡åã«ããããŸãã PMã¯ãos.systemïŒïŒã·ã¹ãã ã³ãã³ããå«ããPythonã³ãŒããå®è¡ã§ãããã¹ãŠã®åŠçãæåéãå®è¡ã§ããŸãã
ãã¹ãŠã®è¯ãããšãçµãããŸã
å±éºãªæŒ¬ç©ã®äœãæ¹ãåŠã¶ã€ããã§ãããããã®éçšã§èª€ã£ãŠæŒ¬ç©ã®ä»çµã¿ãç解ããŸããã ç§ã¯èªãããç§ã¯ãã®ãã¯ã«ã¹ãã·ã³ãæãäžããã®ã奜ãã ã£ãã pickletoolsã®ãœãŒã¹ã³ãŒãã¯å€§ãã«åœ¹ç«ã¡ãŸãããpickleãããã³ã«ãšPMã®è©³çŽ°ã«èå³ãããå Žåã¯ãå§ãããŸãã
çµãã
ãã€ãã®ããã«ãç§ãã¡ã¯ããã§ããŸãã¯ãªãŒãã³ããŒã§ã€ãªã€ã»ã¬ãããã«å人çã«å°ããããšãã§ããé¡ãã質åãåŸ ã£ãŠããŸãã