|
2 | 2 | # ipwndfu: open-source jailbreaking tool for older iOS devices |
3 | 3 | # Author: axi0mX |
4 | 4 |
|
5 | | -import binascii, datetime, getopt, hashlib, struct, subprocess, sys, time |
| 5 | +import binascii, datetime, getopt, hashlib, struct, sys, time |
6 | 6 | import usb # pyusb: use 'pip install pyusb' to install this module |
7 | | -import dfu, recovery, steaks4uce, limera1n, SHAtter |
| 7 | +import dfu, recovery, steaks4uce, limera1n, SHAtter, utilities |
8 | 8 |
|
9 | 9 | EXEC_MAGIC = 'exec'[::-1] |
10 | 10 | AES_BLOCK_SIZE = 16 |
11 | 11 | AES_GID_KEY = 0x20000200 |
12 | 12 | AES_UID_KEY = 0x20000201 |
13 | 13 | AES_ENCRYPT = 16 |
14 | 14 | AES_DECRYPT = 17 |
15 | | -SECUREROM_FILENAME_FORMAT = 'SecureROM-%s-RELEASE.dump' |
16 | | -SRTG_FORMAT = 'SRTG:[iBoot-%s]' |
17 | 15 |
|
18 | 16 | def empty_img3_data(size): |
19 | 17 | assert size >= 20 |
20 | 18 | return struct.pack('<4s3I4s', 'Img3'[::-1], size, 0, 0, 'zero'[::-1]) + '\x00' * (size - 20) |
21 | 19 |
|
22 | | -def apply_patches(file, patches): |
23 | | - # TODO: Should always be the same for decrypted IMG3s from this script, but don't hardcode this. |
24 | | - IMG3_DATA_OFFSET = 0x40 |
25 | | - for (offset, data) in patches: |
26 | | - file = file[:IMG3_DATA_OFFSET + offset] + data + file[IMG3_DATA_OFFSET + offset + len(data):] |
27 | | - return file |
28 | | - |
29 | | -def aes_decrypt(payload, iv, key): |
30 | | - if len(key) == 32: |
31 | | - aesType = 128 |
32 | | - elif len(key) == 64: |
33 | | - aesType = 256 |
34 | | - else: |
35 | | - print 'ERROR: Bad AES key given to aes_decrypt. Exiting.' |
36 | | - sys.exit(1) |
37 | | - p = subprocess.Popen(['openssl', 'enc', '-aes-%s-cbc' % aesType, '-d', '-nopad', '-iv', iv, '-K', key], |
38 | | - stdout=subprocess.PIPE, |
39 | | - stdin=subprocess.PIPE, |
40 | | - stderr=subprocess.PIPE) |
41 | | - (stdoutdata, stderrdata) = p.communicate(input=payload) |
42 | | - |
43 | | - if len(stderrdata) > 0: |
44 | | - print 'ERROR: OpenSSL reported error: %s' % stderrdata |
45 | | - sys.exit(1) |
46 | | - return stdoutdata |
47 | | - |
48 | 20 | class Image3: |
49 | 21 | def __init__(self, data): |
50 | 22 | (self.magic, self.totalSize, self.dataSize, self.signedSize, self.type) = struct.unpack('4s3I4s', data[0:20]) |
@@ -101,7 +73,7 @@ class Image3: |
101 | 73 | keybag = self.getKeybag() |
102 | 74 | device = PwnedDFUDevice() |
103 | 75 | decrypted_keybag = device.decrypt_keybag(keybag) |
104 | | - return aes_decrypt(self.getPayload(), binascii.hexlify(decrypted_keybag[:16]), binascii.hexlify(decrypted_keybag[16:])) |
| 76 | + return utilities.aes_decrypt(self.getPayload(), binascii.hexlify(decrypted_keybag[:16]), binascii.hexlify(decrypted_keybag[16:])) |
105 | 77 |
|
106 | 78 | def newDecryptedImage3(self): |
107 | 79 | typeTag = self.getTags('TYPE'[::-1]) |
@@ -321,7 +293,7 @@ class PwnedDFUDevice(): |
321 | 293 |
|
322 | 294 | self.config = None |
323 | 295 | for config in configs: |
324 | | - if SRTG_FORMAT % config.version in self.identifier: |
| 296 | + if 'SRTG:[iBoot-%s]' % config.version in self.identifier: |
325 | 297 | self.config = config |
326 | 298 | break |
327 | 299 | if self.config is None: |
@@ -571,7 +543,7 @@ class PwnedDFUDevice(): |
571 | 543 | (0x14954, 'run\x00'), # patch 'reset' command string to 'run' |
572 | 544 | (0x17654, struct.pack('<I', 0x41000001)), # patch 'reset' command handler to LOAD_ADDRESS + 1 |
573 | 545 | ] |
574 | | - patchediBSS = apply_patches(decryptediBSS, n88ap_iBSS_435_patches) |
| 546 | + patchediBSS = decryptediBSS[:64] + utilities.apply_patches(decryptediBSS[64:], n88ap_iBSS_435_patches) |
575 | 547 |
|
576 | 548 | device = dfu.acquire_device() |
577 | 549 | assert self.identifier == device.serial_number |
@@ -733,12 +705,12 @@ if __name__ == '__main__': |
733 | 705 |
|
734 | 706 | device = PwnedDFUDevice() |
735 | 707 | dump = device.read_memory(address, length) |
736 | | - subprocess.Popen(['xxd', '-o', str(address)], stdin=subprocess.PIPE).communicate(input=dump) |
| 708 | + print utilities.hex_dump(dump, address), |
737 | 709 |
|
738 | 710 | if opt == '--dump-rom': |
739 | 711 | device = PwnedDFUDevice() |
740 | 712 | securerom = device.securerom_dump() |
741 | | - filename = SECUREROM_FILENAME_FORMAT % device.config.version |
| 713 | + filename = 'SecureROM-%s-RELEASE.dump' % device.config.version |
742 | 714 | f = open(filename, 'wb') |
743 | 715 | f.write(securerom) |
744 | 716 | f.close() |
|
0 commit comments