Marshal loading and exec-ing

2019-06-13 17:03发布

问题:

I have this Python code:

import marshal, imp
if imp.get_magic() == '\x03\xf3\r\n':
    __code = marshal.loads('c\x00\x00\x00\x00.....\x00d\x01\x00k\x00.....\t\t\r\x01')
del marshal, imp
exec __code

The if condition checks wheter the Python version is the "right" version. Then marshal is used to load a string containing some code.

First question: How was that string generated? Maybe compile()? But how exactly? and second question: Can I decompile that string? How?

回答1:

As far as how its created, its something like this

a = marshal.dumps(compile("def test(): return 0", "<source>", "exec"))

As far as working out what it does? You should never unmarshal it. You don't know what nugget of horror is hidden in there and will get executed when you load it in.

You could probably use dis

print dis.disassemble_string(a)

This will give you each operation in the code.

The output of dis'ing the test function

>>    0 DUP_TOPX            0
      3 STOP_CODE      
>>    4 STOP_CODE      
      5 STOP_CODE      
      6 STOP_CODE      
      7 STOP_CODE      
>>    8 STOP_CODE      
      9 POP_TOP        
     10 STOP_CODE      
     11 STOP_CODE      
     12 STOP_CODE      
>>   13 BINARY_AND     
     14 STOP_CODE      
     15 STOP_CODE      
     16 STOP_CODE      
     17 POP_JUMP_IF_TRUE    13
     20 STOP_CODE      
     21 STOP_CODE      
     22 LOAD_CONST          0 (0)
     25 MAKE_FUNCTION       0
     28 STORE_NAME          0 (0)
     31 LOAD_CONST          1 (1)
... etc etc

Its down to you to work through each operation and identify what it is doing. I can spot a few instructions I understand like 34 RETURN_VALUE but the documentation here should help identify the rest