示例#1
0
def Extract_Menu(src, dst):
    table = normal_table('mmbn2.tbl')
    
    with open(src, "rb") as data:

        # Não preciso disso aqui na verdade...
        # main_pointers = []
        # fd.seek( 0x2282c )
        # print ">> Buffering pointer to pointers..."
        # while fd.tell() < 0x228a8 :
            # main_pointers.append(struct.unpack("<L", fd.read(4))[0] & 0xFFFFFF)
            
        text_pointers = [0x7d7bc8,]
        # fd.seek( 0x228a8 )
        # print ">> Buffering pointer to text..."
        # while fd.tell() < 0x22b34 :
            # text_pointers.append(struct.unpack("<L", fd.read(4))[0] & 0xFFFFFF)        
        
        i = 0
        for j, pointer_2 in enumerate(text_pointers):
            if pointer_2 == 0:
                continue
        
            print ">> Extracting {0} {1} text".format(i,j)
            #ret = lzss.uncompress( fd, pointer_2 )
            
            # data = mmap.mmap( -1, len(ret) )
            # data.write(ret)
            data.seek(pointer_2)
    
            # Bufferiza os ponteiros
            entries = struct.unpack("<H" , data.read(2))[0]/ 2
            
            pointers = []
            data.seek(pointer_2)
            for _ in range(entries):
                pointers.append(struct.unpack("<H", data.read(2))[0])
            
            buffer = array.array("c")
            
            
            while True:            
                p = data.tell() - pointer_2
                if p in pointers:
                    for k, ptr in enumerate( pointers ):
                        if p == ptr:
                            # Coloca labels no texto
                            buffer.extend( "<@PointerIdx%d>\n" % k )   
                                    
                b = data.read(1)                   
                c = struct.unpack("B", b)[0]     
                
                if c >= 0xE5: # É uma tag.. esse teste é o mesmo do jogo
                    if c in tagsdict:
                        tagsdict[c][1](data, buffer, tagsdict[c][0])                                            
                    else:
                        buffer.extend( "<"+str(hex(c))+">" )                                
                else:            
                    if b in table:
                        buffer.append( table[b] )
                    else:
                        buffer.extend( "<"+str(hex(c))+">")                            
                
                if data.tell() == 0x7d8d8f:
                    break
                    
            data.close()
                
            output = open(os.path.join(dst, "%03d_%03d.txt" %(i,j)), "w")
            buffer.tofile(output)
            output.close()  
示例#2
0
def Insert_NPC(src, dst):
    global BASE_PTR
    table = normal_table('mmbn2.tbl')    
    table.set_mode('inverted')
    
    files = filter(lambda x: x.__contains__('.txt'), scandirs(src))       
    # Cria o dicionário invertido de tags
    itagsdict = dict([[v[0],k] for k,v in tagsdict.items()])
   
    print hex(BASE_PTR)
    dest = open(dst, 'r+b')
    dest.seek( BASE_PTR )
    
    pointer_files = []
    
    for i, txtname in enumerate(files):
        print ">> Convertendo e comprimindo " + txtname 

        buffer = array.array("c")
        with open(txtname, 'rb') as fd:
            
            pointer_idx = []
        
            for j, line in enumerate(fd):
                #try:
                    line = line.strip('\r\n')
                    if not line:
                        continue
                    elif line in ( "!---------------------!","!+++++++++++++++++++++!","!*********************!" ):
                        continue
                    else:
                        splitted = re.split( TAG_IN_LINE, line )
                        for string in splitted:
                            tag = re.match( GET_TAG, string )
                            # Se não for uma tag, é texto plano
                            if not tag:                            
                                for char in string:
                                    try:
                                        buffer.extend( table[char] )
                                    except:
                                        print "Line {0} Char {1} Text {2}".format(j, ord(char), line)
                                        raise Exception()
                            # Se for uma tag
                            else:
                                tag = tag.groups()[0]
                                argv = []
                                # Tag com argumentos
                                if ": " in tag:
                                    tag,argv = tag.split(": ")
                                    argv = argv.split(" ")
                                    
                                if tag.startswith("@"): # São labels
                                    if "PointerIdx" in tag:
                                        pointer_idx.append( len(buffer) )
                                    else:
                                        print "Line {0} Label {1} Text {2}".format(j, tag, line)
                                        raise Exception()
                                else:                                                                    
                                    if tag in itagsdict:
                                        buffer.extend( struct.pack("B", itagsdict[tag]) )
                                        for arg in argv:
                                            buffer.extend( struct.pack("B", int(arg)) )                            
                                    else:
                                        buffer.extend( struct.pack("B", int(tag,16)) )                                        
                # except:
                    # print "<< Error"
                    # sys.exit()
                    
            size = len(pointer_idx) * 2 + len(buffer)
            temp = mmap.mmap(-1, size)
            offset = len(pointer_idx) * 2
            for ptr in pointer_idx:
                temp.write( struct.pack("<H", offset+ptr) )
            temp.write(buffer.tostring())
            
            ret = lzss.compress(temp) 
            temp.close()
            
            b,name = os.path.split( txtname )
            i, j = name.replace(".txt", "").split("_")

            pointer_files.append( [int(i), int(j), dest.tell()] )            
            ret.tofile(dest)
            

    BASE_PTR = dest.tell()
            
    print ">> Updating pointer table..."    
    for desc in pointer_files:
        dest.seek( 0x228a8 + 4*desc[1] )
        dest.write( struct.pack("<L", desc[2] | 0x08000000) )

    dest.close()                     
示例#3
0
def Extract_Main(src, dst):
    table = normal_table('mmbn2.tbl')
    
    main_pointers = [(0x77d71c, 0x79cb18),]  
    
    with open(src, "rb") as fd:

        # Não preciso disso aqui na verdade...
        # main_pointers = []
        # fd.seek( 0x2282c )
        # print ">> Buffering pointer to pointers..."
        # while fd.tell() < 0x228a8 :
            # main_pointers.append(struct.unpack("<L", fd.read(4))[0] & 0xFFFFFF)
        
        for i, pp in enumerate(main_pointers):
            text_pointers = []
            fd.seek( pp[0] )
            print ">> Buffering pointer to text..."
            
            ret = fd.read(pp[1]-pp[0])
            data = mmap.mmap( -1, len(ret) )
            data.write(ret)
            
            data.seek(0)
            j = 0
            while True:        
                # Bufferiza os ponteiros
                while data.tell() % 4 != 0: data.read(1)
                
                offset = data.tell()
                entries = data.read(2)
                if len(entries) == 0: break
                
                print ">> Extracting {0} {1} text".format(i,j)
                entries = struct.unpack("<H" , entries)[0]/ 2
                
                pointers = []
                data.seek(-2,1)
                for _ in range(entries):
                    pointers.append(struct.unpack("<H", data.read(2))[0])
                
                buffer = array.array("c")
                buffer.extend( "<@AbsoluteAddr %d>\n" % (pp[0]+offset) )  
                
                new_eb = True
                while True:            
                    p = data.tell() - offset
                    if p in pointers:
                        for k, ptr in enumerate( pointers ):
                            if p == ptr:
                                # Coloca labels no texto
                                buffer.extend( "<@PointerIdx%d>\n" % k )                                
                        
                    b = data.read(1)
                    if len(b) == 0: break            
                    
                    c = struct.unpack("B", b)[0]
                    # Após a tag 0xE7, sempre devemos ler uma nova tag. Se não, podemos dizer que o bloco de leitura acabou
                    if new_eb:
                        if c < 0xE5:
                            data.seek(-1,1)
                            break
                            
                    new_eb = False
                    
                    if c >= 0xE5: # É uma tag.. esse teste é o mesmo do jogo
                        if c in tagsdict:
                            tagsdict[c][1](data, buffer, tagsdict[c][0])                                            
                        else:
                            buffer.extend( "<"+str(hex(c))+">" )                                
                    else:            
                        if b in table:
                            buffer.append( table[b] )
                        else:
                            buffer.extend( "<"+str(hex(c))+">")
                            
                    if c == 0xE7:
                        new_eb = True
                                                
                output = open(os.path.join(dst, "%03d_%03d.txt" %(i,j)), "w")
                buffer.tofile(output)
                output.close()
                
                j += 1
                
            data.close()            
示例#4
0
def Insert_Main(src, dst):
    global BASE_PTR
    table = normal_table('mmbn2.tbl')    
    table.set_mode('inverted')
    
    files = filter(lambda x: x.__contains__('.txt'), scandirs(src))       
    # Cria o dicionário invertido de tags
    itagsdict = dict([[v[0],k] for k,v in tagsdict.items()])
   
    #base_ptr = 0x800000  
    print hex(BASE_PTR)
    dest = open(dst, 'r+b')
    dest.seek( BASE_PTR )
    
    pointer_old = []
    pointer_new = []
    
    for i, txtname in enumerate(files):
        print ">> Convertendo e comprimindo " + txtname 
        
        while dest.tell() % 4 != 0: dest.write("\x00")

        buffer = array.array("c")
        with open(txtname, 'rb') as fd:                       
            
            pointer_idx = []
        
            for j, line in enumerate(fd):
                #try:
                    line = line.strip('\r\n')
                    if not line:
                        continue
                    elif line in ( "!---------------------!","!+++++++++++++++++++++!","!*********************!" ):
                        continue
                    else:
                        splitted = re.split( TAG_IN_LINE, line )
                        for string in splitted:
                            tag = re.match( GET_TAG, string )
                            # Se não for uma tag, é texto plano
                            if not tag:                            
                                for char in string:
                                    try:
                                        buffer.extend( table[char] )
                                    except:
                                        print "Line {0} Char {1} Text {2}".format(j, ord(char), line)
                                        raise Exception()
                            # Se for uma tag
                            else:
                                tag = tag.groups()[0]
                                argv = []
                                # Tag com argumentos
                                if ": " in tag:
                                    tag,argv = tag.split(": ")
                                    argv = argv.split(" ")
                                    
                                if tag.startswith("@"): # São labels
                                    if "PointerIdx" in tag:
                                        pointer_idx.append( len(buffer) )
                                    elif "AbsoluteAddr" in tag:
                                        t,c  = tag.split(" ") # Errei .. faltou o : na tag, para aproveitar o split mais acima
                                        pointer_old.append( struct.pack("<L", int(c) | 0x08000000) )
                                        pointer_new.append( struct.pack("<L", dest.tell() | 0x08000000) )
                                    else:
                                        print "Line {0} Label {1} Text {2}".format(j, tag, line)
                                        raise Exception()
                                else:                                                                    
                                    if tag in itagsdict:
                                        buffer.extend( struct.pack("B", itagsdict[tag]) )
                                        for arg in argv:
                                            buffer.extend( struct.pack("B", int(arg)) )                            
                                    else:
                                        buffer.extend( struct.pack("B", int(tag,16)) )                                        
                # except:
                    # print "<< Error"
                    # sys.exit()
                    
            size = len(pointer_idx) * 2 + len(buffer)
            offset = len(pointer_idx) * 2
            for ptr in pointer_idx:
                dest.write( struct.pack("<H", offset+ptr) )
            dest.write(buffer.tostring())
            
            b,name = os.path.split( txtname )
            i, j = name.replace(".txt", "").split("_")          
     
    BASE_PTR = dest.tell()

    print ">> Updating pointer table..."    
    dest.seek( 0 )
    while dest.tell() < 0x800000:
        ptr = dest.read(4)
        if ptr in pointer_old:
            idx = pointer_old.index(ptr)
            dest.seek(-4,1)
            print ">> Updated %s to %s [%s]" % ( hex(struct.unpack("<L",ptr)[0]) , hex(struct.unpack("<L",pointer_new[idx])[0]) , hex( dest.tell()) )            
            dest.write( pointer_new[pointer_old.index(ptr)])

    dest.close()