Advertisement
Guest User

SoR EBOOT Tool v1

a guest
Sep 24th, 2016
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.06 KB | None | 0 0
  1. import struct
  2. import pdb
  3.  
  4. PTR_COL = 6
  5. s_list = ['世界地図', 'ロンドエール', '円卓の間', '自室', '地下室',
  6.           'フューミの村', '村はずれ', '取引所', '村長の家', 'アーレンティール',
  7.           '森の入口', '交易所', '大樹の館', 'エセルガルド', '城砦周辺',
  8.           '闇の行商人', '正門前', 'ミストアイル', '氷の断崖',
  9.           'ドワーフの道具屋', '穴ぐら', 'グロムバルク', '城門', '商店', '王宮']
  10. s_list1 = [True] * len(s_list)
  11. s_list2 = [[]] * len(s_list)
  12. s_list3 = [False] * len(s_list)
  13. block_list = [0x14f46c, 0x14f6fc, 0x14f944, 0x14fc54,
  14.               0x1501bc, 0x1504bc, 0x150c5c, 0x150fa4, 0x1511d4, 0x151464,
  15.               0x153edc, 0x154194, 0x15447c, 0x154854, 0x154b24, 0x154e84,
  16.               0x1550b4, 0x1554b4, 0x1556e4, 0x156324, 0x15658c, 0x156894,
  17.               0x156c4c, 0x156f24, 0x1572c4, 0x15858c, 0x158d44, 0x158fbc,
  18.               0x15938c, 0x15961c, 0x159acc, 0x159d2c, 0x159f6c, 0x15a1dc,
  19.               0x15a424, 0x15a664, 0x15a8bc, 0x15ac8c, 0x15aebc, 0x15b0ec,
  20.               0x15b444, 0x15b674, 0x15b8ac, 0x15d2c8, 0x15d56c, 0x15d79c,
  21.               0x15eae4, 0x15f00c, 0x15fc94, 0x15ffd4, 0x1602a4, 0x160cec,
  22.               0x161074, 0x1612cc, 0x1614fc, 0x16180c, 0x161a84, 0x161cb4,
  23.               0x161eec, 0x16213c, 0x1623ac, 0x16279c, 0x162d64, 0x16334c,
  24.               0x16383c, 0x163a6c, 0x164104, 0x164764, 0x1649bc, 0x164c4c,
  25.               0x164e94, 0x1650c4, 0x1652f4, 0x16586c, 0x1662b4, 0x16650c,
  26.               0x16673c, 0x16696c, 0x166c74, 0x166ea4, 0x1670d4, 0x167624,
  27.               0x167b4c, 0x167dbc, 0x167fec, 0x16846c, 0x168ab4, 0x168ebc,
  28.               0x16917c, 0x169424, 0x1696d4, 0x1779fc, 0x177c6c, 0x177ebc,
  29.               0x1781c4, 0x178584, 0x178834, 0x178b44, 0x178d74, 0x178fc4,
  30.               0x1791f4, 0x1795ec, 0x1798e4, 0x179d5c, 0x179f8c, 0x17a1bc,
  31.               0x17a3ec, 0x17a634, 0x17a874, 0x17ab0c, 0x17ad5c, 0x17af8c,
  32.               0x17b1bc, 0x17b46c, 0x17b6a4, 0x17bad4, 0x17bea4, 0x17c42c,
  33.               0x17c65c, 0x17c894, 0x17cac4, 0x17cd24, 0x17cfbc, 0x17d23c,
  34.               0x17d46c, 0x17d71c, 0x17dad4, 0x17dd94, 0x17e1ac, 0x17e474,
  35.               0x17e774, 0x17e9ac, 0x17ebec, 0x17efb4, 0x17f22c, 0x17f494,
  36.               0x180afc, 0x180d3c, 0x180fdc, 0x1813c4, 0x18162c]
  37. blockiter = iter(block_list)
  38.  
  39. def update_ptr(ptr, orig_pos, new_pos):
  40.     if ptr[0] == '^':
  41.         MSBflag = True
  42.         ptr = ptr[1:]
  43.     else:
  44.         MSBflag = False
  45.     ptr = int(ptr, 16)
  46.     if ptr < 0x200000:
  47.         filedata[ptr:ptr+4] = struct.pack('<I', new_pos)
  48.     else:
  49. ##        print(hex(addr))
  50.         orig_pos -= 0xC0
  51.         ptr -= 0x8803F40
  52.         new_pos -= 0x8804000
  53.         if new_pos & 0xFFFF >= 0x8000:
  54.             new_pos += 0x10000
  55.         filedata[ptr:ptr+2] = struct.pack('<H', new_pos >> 16)
  56.         if MSBflag:
  57.             return
  58.         ptr = filedata.find(struct.pack('<H', orig_pos & 0xFFFF), ptr)
  59.         filedata[ptr:ptr+2] = struct.pack('<H', new_pos & 0xFFFF)
  60.  
  61. def eboot_transform():
  62.     '''unwind EBOOT relocations'''
  63.     with open('ULJS00548.BIN', 'rb') as f:
  64.         filedata = bytearray(f.read())
  65.     pos = 0x312b04
  66.     end = pos + 0x6de90
  67.     count = 0
  68.     while pos < end:
  69.         if struct.unpack('<I', filedata[pos+4:pos+8])[0] == 2:
  70.             tgt = struct.unpack('<I', filedata[pos:pos+4])[0] + 0xC0
  71.             val = struct.unpack('<I', filedata[tgt:tgt+4])[0]
  72.             filedata[tgt:tgt+4] = struct.pack('<I', val + 0x8804000)
  73.             filedata[pos:pos+8] = b'\x00' * 8
  74.         pos += 8
  75.     return filedata
  76.  
  77. filedata = eboot_transform()    #Unwinding eboot relocations
  78. #Blank out the 2nd block
  79. filedata[0x14EEC0:0x14EFF0] = b'\x00' * (0x14EFF0 - 0x14EEC0)
  80. count = 0
  81. insert_point = 0x14E944         #First string goes here
  82. block_end = insert_point + 300  #When to switch to the 2nd block
  83. #Read input file data
  84. inputdata = []
  85. with open('all.tsv', 'r', encoding='utf-8') as f:
  86.     for line in f:
  87.         ptrs = []
  88.         line = line.rstrip('\r\n').split('\t')
  89.         if line[0] != '':           #New entry
  90. #Read in the pointer list
  91.             c = PTR_COL
  92.             while c < len(line):
  93.                 if line[c] == '':
  94.                     break
  95.                 else:
  96.                     ptrs.append(line[c])
  97.                     c += 1
  98. #Add entry to list. Format = addr, origtext, newtext, ptrs
  99.             inputdata.append([int(line[0], 16), line[4], line[5], ptrs])
  100.         else:                       #Continuation entry
  101. #Add data to previous entry
  102.             inputdata[-1][1] += '\n' + line[4]
  103.             inputdata[-1][2] += '\n' + line[5]
  104. deleted = 0
  105. for i, (addr, orig_text, text, ptrs) in enumerate(list(inputdata)):
  106.     if orig_text in s_list:         #Entry is in the list at the top
  107.                                     #These repeat many times, like over 100
  108. #Delete from list. We don't want to come back to it later
  109.         del inputdata[i - deleted]
  110.         deleted += 1
  111.         index = s_list.index(orig_text)     #Get index number
  112.         flag = s_list1[index]               #Get flag. True = Not processed yet
  113.         if flag:                                        #Not processed yet
  114.             s_list1[index] = False                      #Set flag
  115.             if insert_point + len(text) < block_end:    #Check for end of block
  116.                 pass
  117.             else:                                       #Switch to 2nd block
  118.                 insert_point = 0x14EEC4
  119.                 block_end = insert_point + 300
  120.             text = text.encode('cp932')                 #Convert to bytes
  121.             text += b'\x00' * (4 - len(text) % 4)       #Pad to word-aligned
  122. #Insert the text
  123.             filedata[insert_point:insert_point+len(text)] = text
  124. #Set the pointer for where this text can be found
  125.             s_list2[index] = insert_point + 0x8803F40
  126.             insert_point += len(text)                   #Advance pointer
  127.         else:                                           #Already processed
  128.             if s_list3[index]:                          #3rd (or later time)
  129.                 end = filedata.find(b'\x00', addr)      #Blank out the string
  130.                 filedata[addr:end] = b'\x00' * (end-addr)
  131.             else:                                       #2nd time
  132.                 s_list3[index] = True                   #Set flag
  133.         for ptr in ptrs:                                #Update pointers
  134.             update_ptr(ptr, addr, s_list2[index])
  135. insert_point = next(blockiter)
  136. block_end = insert_point + 300
  137. for i, (addr, orig_text, text, ptrs) in enumerate(reversed(inputdata)):
  138.     if text != orig_text and text != '':
  139.         text = text.encode('cp932')
  140.         end = filedata.find(b'\x00', addr)              #Compute available space
  141.         while filedata[end] == 0:
  142.             end += 1
  143.         avail_space = end - 1 - addr
  144.         if len(text) <= avail_space:                    #Enough space
  145.             text += b'\x00' * (4 - len(text) % 4)       #Pad to word-aligned
  146.             filedata[addr:addr+len(text)] = text        #Insert text
  147.         else:                                           #Not enough space
  148.             if ptrs == []:
  149.                 print(hex(addr))
  150.                 continue        #Need pointers to move if not enough space
  151.             filedata[addr:end] = b'\x00' * (end-addr)   #Blank out the string
  152.             text += b'\x00' * (4 - len(text) % 4)       #Pad to word-aligned
  153.             if insert_point + len(text) < block_end:    #Enough space in block
  154.                 pass
  155.             else:                                       #Not enough, go to next
  156.                 insert_point = next(blockiter)          #block
  157.                 block_end = insert_point + 300
  158.             filedata[insert_point:insert_point+len(text)] = text
  159.             for ptr in ptrs:                            #Update pointers
  160.                 update_ptr(ptr, addr, insert_point + 0x8803F40)
  161.             insert_point += len(text)                   #Advance pointer
  162.        
  163.        
  164. with open('EBOOT.BIN', 'wb') as f:
  165.     f.write(filedata)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement