mirror of
https://github.com/wiiu-env/ROBChain.git
synced 2024-12-12 11:44:22 +01:00
88 lines
3.0 KiB
Python
88 lines
3.0 KiB
Python
from ropgadgets import *
|
|
from common_defines import *
|
|
import struct
|
|
|
|
|
|
def load_code_bin_ropchain_calls(target_addr, extra_data_addr, rpl_name_addr, function_name_addr, payload_data_addr, payload_len):
|
|
cur_chain = []
|
|
# We are on a new thread on Core 1
|
|
# We expected a memory mapping 0xA0000000 -> 0x1000000.
|
|
# Copy our payload to the target_addr
|
|
cur_chain += memcpy(0xC1000000 + target_addr, payload_data_addr, payload_len)
|
|
cur_chain += DCFlushRange(target_addr, payload_len)
|
|
cur_chain += ICInvalidateRange(target_addr, payload_len)
|
|
|
|
# Create a main hook to execute the payload on the next application switch.
|
|
cur_chain += memcpy(0xC1000000 + ADDRESS_main_entry_hook, extra_data_addr, 4)
|
|
cur_chain += DCFlushRange(ADDRESS_main_entry_hook, 4)
|
|
cur_chain += ICInvalidateRange(ADDRESS_main_entry_hook, 4)
|
|
|
|
# Call _SYSLaunchMiiStudio() and exit the thread
|
|
cur_chain += FindExportAndCall(extra_data_addr + 0x04, rpl_name_addr, function_name_addr) # _SYSLaunchMiiStudio
|
|
cur_chain += OSExitThread(0)
|
|
|
|
return cur_chain
|
|
|
|
|
|
def load_code_bin_ropchain_data(base, path, entrypoint_addr):
|
|
cur_chain = []
|
|
|
|
extra_data_addr = base
|
|
tmp_chain = [(entrypoint_addr & 0x03fffffc) | 0x48000003, # branch to target_addr
|
|
0,
|
|
0]
|
|
|
|
cur_chain += tmp_chain
|
|
rpl_name_addr = extra_data_addr + (len(tmp_chain) * 4)
|
|
tmp_chain = [0x73797361,
|
|
0x70702E72,
|
|
0x706C0000]
|
|
|
|
cur_chain += tmp_chain
|
|
function_name_addr = rpl_name_addr + (len(tmp_chain) * 4)
|
|
tmp_chain = [0x5F535953,
|
|
0x4C61756E,
|
|
0x63684D69,
|
|
0x69537475,
|
|
0x64696F00]
|
|
|
|
# Copy the target payload into the ROP.
|
|
cur_chain += tmp_chain
|
|
payload_data_addr = function_name_addr + (len(tmp_chain) * 4)
|
|
|
|
tmp_chain = []
|
|
payload_len = 0
|
|
word = 1
|
|
with open(path, "rb") as f:
|
|
while word:
|
|
|
|
word = f.read(4)
|
|
if len(word) == 0:
|
|
break
|
|
val = 0
|
|
if len(word) < 4:
|
|
for x in range(len(word)):
|
|
val |= word[x] << ((3 - x) * 8)
|
|
else:
|
|
val = struct.unpack(">I", word)[0]
|
|
tmp_chain.append(val)
|
|
payload_len += 4
|
|
|
|
cur_chain += tmp_chain
|
|
return [cur_chain, extra_data_addr, rpl_name_addr, function_name_addr, payload_data_addr, payload_len]
|
|
|
|
|
|
def load_code_bin_ropchain(path, target_addr, entrypoint_addr):
|
|
cur_chain = []
|
|
base = 0x4D900000 + 0x14
|
|
# Get the length of the "function calls" to calculates offsets
|
|
rop_len = len(load_code_bin_ropchain_calls(0, 0, 0, 0, 0, 0)) * 4
|
|
|
|
# Create the data for the payload
|
|
tmp_data = load_code_bin_ropchain_data(base + rop_len, path, entrypoint_addr)
|
|
|
|
# Build real ropchain
|
|
cur_chain += load_code_bin_ropchain_calls(target_addr, tmp_data[1], tmp_data[2], tmp_data[3], tmp_data[4], tmp_data[5])
|
|
cur_chain += tmp_data[0]
|
|
return cur_chain
|