
def _bin(x, width):
    return ''.join(str((x>>i)&1) for i in xrange(width-1,-1,-1))

from construct import *
import struct

d_opcode = BitStruct("double_arg",
     BitField("op_code", 4),
     BitField("r1", 14),
     BitField("r2", 14),
)

s_opcode = BitStruct("single_arg",
     BitField("blank", 4),
     BitField("op_code", 4),
     BitField("imm", 10),
     BitField("r1", 14),
)    


def little_endian(bytes):
    _1, _2, _3, _4 = bytes
    return _4+_3+_2+_1

def translate(f, output, *a, **kw):
    f_bytes = f.read(8)
    i_bytes = f.read(4)

    instructions = []
    float_data = []
    
    def decode_instructions_and_data(f_bytes, i_bytes):
        float_data.append(struct.unpack('d', f_bytes)[0])
        instructions.append(little_endian(i_bytes))        
    
    while f_bytes and i_bytes:
        decode_instructions_and_data(f_bytes, i_bytes)
        i_bytes = f.read(4)
        f_bytes = f.read(8)
        if f_bytes and i_bytes:
            decode_instructions_and_data(f_bytes, i_bytes)
            f_bytes = f.read(8)
            i_bytes = f.read(4)
    
    output(instructions, float_data, *a, **kw)

def write_file(python, file_name):
    output_file = open(file_name, "w")
    output_file.write(python)
    output_file.close()
    
    
    
    
    
    
from functools import partial
def generate_bytes(instructions, float_data, do, *a, **kw):
    do("""
{
    "data":
        %(float_data)s
    ,
    "code":
        [%(instructions)s]
}
    """ % dict(
        instructions = ', '.join(map(lambda x:str(x[0]).replace('L',''), map(partial(struct.unpack, 'I'), instructions))),
        float_data = float_data
    ), *a, **kw)

    
def write_bytes(instructions, float_data, filename):
    generate_bytes(instructions, float_data, write_file, filename)    

translate(open("../binaries/bin1.obf", "rb"), write_bytes, "../Python/translated_binaries/bin1.json")
translate(open("../binaries/bin2.obf", "rb"), write_bytes, "../Python/translated_binaries/bin2.json")
translate(open("../binaries/bin3.obf", "rb"), write_bytes, "../Python/translated_binaries/bin3.json")


