Guest User

Nayuta Eboot Insert v2

a guest
Mar 8th, 2015
339
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Insert Nayuta eboot.
  2. # Need decrypted eboot in file boot.orig and ebootdump.csv w/ text to insert
  3. # ebootdump.csv: must be in tab-separated format. Cols beyond the 2nd are ignored
  4. # ebootdump.csv: must be saved with SHIFT-JIS encoding
  5.  
  6. import os
  7. import struct
  8.  
  9. def get_data(filename):
  10.     totalbytes = os.path.getsize(filename)
  11.     infile = open(filename, 'rb')
  12.     totalfiledata = infile.read(totalbytes)
  13.     return totalfiledata
  14.  
  15. def replacestr(origstr,replacestr,startpos,replacelen):
  16. #Returns a string with a replaced sub-string
  17. #origstr - the original string, replacestr = the string to replace
  18. #startpos - where the replacement string should go
  19. #replacelen - how many characters of the original string to replace
  20.     return origstr[:startpos] + replacestr + origstr[startpos+replacelen:]
  21.  
  22. def text_decode(text):
  23. #Changes {} entries in source file into hex
  24.     while '{ ' in text:
  25.         startpos = text.find('{ ')
  26.         endpos = text.find(' }')
  27.         s = text[startpos+1:endpos]
  28.         s = s.translate(None,' ')
  29.         s = s.decode('hex')
  30.         text = text[:startpos] + s + text[endpos+2:]
  31.     return text
  32.  
  33. #Read input data
  34. inputdata = []
  35. with open('ebootdump.csv','rb') as f:
  36.     for line in f:
  37.         line = line.translate(None,"\r\n") #Trims newline characters
  38.         line = line.split('\t')
  39.         line[0] = int(line[0],16)
  40.         if line[2] != '':
  41.             line[2] = int(line[2],16)
  42.         if line[3] != '':
  43.             line[3] = int(line[3])
  44.         inputdata.append(line)
  45.  
  46. filedata = get_data('NPJH50625.BIN')
  47. addr_mov = 0x221FCC #First address to put moved stuff
  48. flag = False
  49. flag2 = False
  50.  
  51. #Goes in reverse order to make room for strings
  52. for addr, text, pointer, pointertype in reversed(inputdata):
  53.     pos = filedata.find('\x00',addr) #Find end of string
  54.     while filedata[pos] == '\x00':   #Find available length for string
  55.         pos += 1
  56.     avail_len = pos - addr - 1
  57.     text = text_decode(text)         #Get the string to insert
  58.     if len(text) > avail_len:        #If the string won't fit...
  59.         if pointer == '' or pointertype == '':
  60.             print 'No pointer available!'
  61.         if pointertype == 1:         #Type 1 pointer: Address in EBOOT
  62.             print 'Attempting to update entry %s - Pointer type 1.' % hex(addr)
  63.             #Zero out the original entry
  64.             filedata = replacestr(filedata,'\00'*avail_len,addr,avail_len)
  65.             #Update the pointer
  66.             filedata = replacestr(filedata,struct.pack('<I',addr_mov-0xc0),
  67.                                   pointer,4)
  68.             #Put the string where moved stuff goes
  69.             filedata = replacestr(filedata,text,addr_mov,len(text))
  70.             #Compute new addr for moved stuff (word aligned)
  71.             addr_mov = addr_mov + len(text) + 1
  72.             while addr_mov % 4 != 0:
  73.                 addr_mov += 1
  74.             #If the first block for moved stuff is exhausted, jump to 2nd block
  75.             if flag == False and addr_mov > 0x2220b0:
  76.                 flag = True
  77.                 addr_mov = 0x223f0c #Address for 2nd block
  78.             #If the second block for moved stuff is exhausted, jump to 3rd block
  79.             if flag2 == False and addr_mov > 0x223ff8:
  80.                 flag2 = True
  81.                 addr_mov = 0x224d18 #Address for 3rd block
  82.         elif pointertype in (2,3):  #Type 2/3 pointers are LI instructions
  83.             #Type 2 is standard LI. Type 3 is split LI where there is a
  84.             #one instruction delay between the halves
  85.             print 'Attempting to update entry %s - Pointer type %d.' % \
  86.                   (hex(addr),pointertype)
  87.             #Zero out the original entry
  88.             filedata = replacestr(filedata,'\00'*avail_len,addr,avail_len)
  89.             #Compute the EBOOT pointer address
  90.             pointer = pointer - 0x8803f40
  91.             #Replace the high-order bits of the target address
  92.             filedata = replacestr(filedata,struct.pack('<I',addr_mov-0xc0)[2:4],
  93.                                   pointer,2)
  94.             #Move the pointer to the low-order bits of the target address
  95.             if pointertype == 2:
  96.                 pointer += 4
  97.             else:
  98.                 pointer += 8
  99.             #Replace the low-order bits of the target address
  100.             filedata = replacestr(filedata,struct.pack('<I',addr_mov-0xc0)[0:2],
  101.                                   pointer,2)
  102.             #Put the new string where moved stuff goes
  103.             filedata = replacestr(filedata,text,addr_mov,len(text))
  104.             #Compute new addr for moved stuff (word aligned)
  105.             addr_mov = addr_mov + len(text) + 1
  106.             while addr_mov % 4 != 0:
  107.                 addr_mov += 1
  108.             if flag == False and addr_mov > 0x2220b0:
  109.                 flag = True
  110.                 addr_mov = 0x223f0c
  111.             if flag2 == False and addr_mov > 0x223ff8:
  112.                 flag2 = True
  113.                 addr_mov = 0x224d18
  114.         else:
  115.             #If we don't know the pointer, all we can do is truncate to fit
  116.             print "Text %s at address %s len is %d; max len is %d" \
  117.                   % (text, hex(addr), len(text), avail_len)
  118.             text = text[:avail_len]
  119.             text = text + (avail_len - len(text))*'\x00'
  120.             filedata = replacestr(filedata,text,addr,avail_len)
  121.     else:   #This block is for if the string will fit in the available space
  122.         text = text + (avail_len - len(text))*'\x00'
  123.         filedata = replacestr(filedata,text,addr,avail_len)
  124.  
  125. #Write output
  126. outfile = open('EBOOT.BIN','wb')
  127. outfile.write(filedata)
  128. outfile.close()
RAW Paste Data