Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import binascii
- import struct
- import subprocess
- import pdb
- #0x08A99E80 0x33a540
- TEXT_COL = 5
- POINTER_COL = 6
- del_space = str.maketrans({' ':None})
- def text_decode(s):
- while '{' in s:
- pos = s.find('{')
- endpos = s.find('}')
- s1 = binascii.unhexlify(s[pos+1:endpos].translate(del_space)).decode('ascii')
- s = s[:pos] + s1 + s[endpos+1:]
- return s.encode('cp932')
- def update_pointer(filedata, addr, addr_orig, ptr):
- #Changes a pointer.
- #addr is where the text is
- #addr_orig is where the text was
- #ptr is where the pointer is
- msb = True #"Replace MSB" - most significant bits of pointer
- lsb = True #"Replace LSB"
- addr1 = addr #These are here for printing / debugging, they're not used
- addr2 = addr_orig
- if ptr[0] != '0': #"Standard pointer" starts with 0
- special_flag = True
- if ptr[0] == '^': #"Special pointer" msb only has "^" appended
- lsb = False
- elif ptr[0] == '&': #"Special pointer" lsb only has "&" appended
- msb = False
- else:
- print(ptr)
- print('error1', hex(addr_orig), ptr)
- quit()
- ptr = int(ptr[1:], 16)
- else:
- special_flag = False
- ptr = int(ptr, 16)
- if ptr < 0x8804000: #Word pointer (easy)
- filedata[ptr:ptr+4] = struct.pack('<I', addr - 0xC0)
- else: #LI-style pointer, specified by virtual address
- #Some debugging stuff
- # print(hex(addr_orig), hex(ptr), (addr + 0x8803F40) & 0xFFFF >= 0x8000,
- # (addr_orig + 0x8803F40) & 0xFFFF >= 0x8000)
- #No idea what's going on here. Programming by guess and check
- #Those relocations are what's messing me up.
- if (addr + 0x8803F40) & 0xFFFF >= 0x8000 and \
- (addr_orig + 0x8803F40) & 0xFFFF >= 0x8000:
- addr += 0x10000
- addr_orig += 0x10000
- elif (addr + 0x8803F40) & 0xFFFF < 0x8000 and \
- (addr_orig + 0x8803F40) & 0xFFFF >= 0x8000:
- addr_orig += 0x10000
- addr += 0x10000
- elif (addr + 0x8803F40) & 0xFFFF >= 0x8000 and \
- (addr_orig + 0x8803F40) & 0xFFFF < 0x8000:
- pass
- ptr -= 0x8803F40 #Convert to physical address
- addr = struct.pack('<I', addr - 0xC0) #Where the text will be
- addr_orig = struct.pack('<I', addr_orig - 0xC0) #Where the text was
- if msb == True: #Replace MSB
- msbaddr = ptr
- filedata[ptr:ptr+2] = addr[2:]
- if lsb == True: #Replace LSB
- if not special_flag:
- while True:
- searchedfor = addr_orig[:2] #For debugging, not used
- #Search for the lsb part of the pointer
- ptr = filedata.find(addr_orig[:2], ptr + 1)
- if ptr == -1: #Not found
- print('error2', binascii.hexlify(addr_orig), binascii.hexlify(searchedfor))
- quit()
- #Make sure this is really it. Looking for addiu opcode.
- # print('hit', ptr % 4 == 0, filedata[ptr+3] >> 4 == 2)
- if ptr % 4 == 0:
- break
- lsbaddr = ptr #For debugging, not used
- filedata[ptr:ptr+2] = addr[:2] #Replace LSB
- if msb and lsb:
- if lsbaddr - msbaddr > 0xC:
- print(hex(addr1+0x8803f40), hex(addr2), hex(msbaddr + 0x8803F40), hex(lsbaddr + 0x8803F40),
- binascii.hexlify(searchedfor))
- return filedata
- def CSVfix(filedata):
- start = 0x0891B458 - 0x8803F40
- end = 0x0891C010 - 0x8803F40
- s = binascii.unhexlify('2C000224')
- s1 = binascii.unhexlify('1F000224')
- pos = start
- while pos < end:
- if filedata[pos:pos+4] == s:
- filedata[pos:pos+4] = s1
- pos += 4
- return filedata
- with open('EBOOTBASE.bin', 'rb') as f: #Has extra program header and 0x2000 bytes at the end
- filedata = bytearray(f.read())
- filedata = CSVfix(filedata)
- with open('data1.tsv', 'r', encoding='utf-8') as f: #Read data
- inputdata = []
- for line in f:
- line = line.rstrip('\r\n').split('\t')
- if line[0] == '':
- inputdata[-1][1].append(text_decode(line[TEXT_COL]))
- else:
- line[0] = int(line[0], 16)
- col = POINTER_COL
- pointers = []
- while line[col] != '':
- pointers.append(line[col])
- col += 1
- if col == len(line):
- break
- inputdata.append([line[0], [text_decode(line[TEXT_COL])], pointers])
- inserted_strings = [] #Keep track of inserted strings
- nextpos = 0x33A540 #Keep track of insert point within the new 0x2000 segment
- for addr, lines, pointers in sorted(inputdata, key=lambda x: x[0], reverse=True):
- addr_orig = addr #Needed to call update_pointer
- avail_len = filedata.find(b'\x00', addr)
- while filedata[avail_len] == 0:
- avail_len += 1
- avail_len = avail_len - addr - 1
- ## print(avail_len)
- s = b'\n'.join(lines) #Get the string to insert
- ## if s in [x[1] for x in inserted_strings]: #Already there
- #### print(hex(addr))
- ## filedata[addr:addr+avail_len] = b'\x00' * avail_len #Blank out the string
- ## for addr, s1 in inserted_strings: #Find where the string is
- ## if s == s1:
- ## break
- ## else:
- ## print('error3')
- ## quit()
- ## for ptr in pointers: #Update each pointer
- ## filedata = update_pointer(filedata, addr, addr_orig, ptr)
- ## continue
- inserted_strings.append([addr, s]) #Add the string and position to the list
- if len(s) > avail_len: #Not enough space
- filedata[addr:addr+avail_len] = b'\x00' * avail_len #Blank out the string
- inserted_strings[-1][0] = nextpos - 0xA46C0 + 0xC0 #Update inserted_strings with new position
- s += b'\x00' * (4 - (len(s) % 4)) #Pad out string with nulls
- filedata[nextpos:nextpos+len(s)] = s #write the string
- for ptr in pointers: #update each pointer
- filedata = update_pointer(filedata, nextpos - 0xA46C0 + 0xC0, addr_orig, ptr)
- nextpos += len(s) #update string insert position
- else: #enough space
- filedata[addr:addr+avail_len] = b'\x00' * avail_len #Blank out the string
- filedata[addr:addr+len(s)] = s #Replace the string
- with open('EBOOT.BIN', 'wb') as f:
- f.write(filedata)
- subprocess.run(['armipsd', 'YsVsSora.asm'])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement