@@ -461,7 +461,6 @@ In r2:
461461
462462We search for the pattern , then seek backwards for a "cbz w0, ..." with positive offset. If we find none
463463within a short range , we skip this match , otherwise we replace th at instruction with an unconditional branch.
464-
465464* /
466465
467466sym fuse_jump
@@ -514,3 +513,195 @@ sym fuse_jump
514513 bfi w8 , w12 , 0 , 26
515514 str w8 , [ x10 ]
516515 ret
516+
517+
518+ // void antitrust(volatile void * boot_image)
519+
520+ / *
521+ Keep TrustZone unlocked.
522+
523+ There are a total of 4 variants of this patch , and this is just one of them.
524+ In the matrix below:
525+
526+ - s2 = A10 + on iOS 14 . 0 + . Stage2 - only.
527+ - XX = A7 , any version , and A8 - A9 on 10 .x and lower. Pongo - only.
528+ - YY = A9X , any version. Pongo - only.
529+ - ZZ = The rest , this is us. The only patch th at is shared between stage2 and Pongo.
530+
531+ For A8 - A9 , ZZ could be used on iOS 8 and 10 as well , but not on iOS 9 .
532+ But XX works on those too , so we don't care.
533+
534+ +--------+----+----+-----+----+-----+-----+------+----+-----+
535+ | | A7 | A8 | A8X | A9 | A9X | A10 | A10X | T2 | A11 |
536+ +--------+----+----+-----+----+-----+-----+------+----+-----+
537+ | iOS 7 | XX | | | | | | | | |
538+ +--------+----+----+-----+----+-----+-----+------+----+-----+
539+ | iOS 8 | XX | XX | XX | | | | | | |
540+ +--------+----+----+-----+----+-----+-----+------+----+-----+
541+ | iOS 9 | XX | XX | XX | XX | YY | | | | |
542+ +--------+----+----+-----+----+-----+-----+------+----+-----+
543+ | iOS 10 | XX | XX | XX | XX | YY | ZZ | ZZ | | |
544+ +--------+----+----+-----+----+-----+-----+------+----+-----+
545+ | iOS 11 | XX | ZZ | ZZ | ZZ | YY | ZZ | ZZ | ZZ | ZZ |
546+ +--------+----+----+-----+----+-----+-----+------+----+-----+
547+ | iOS 12 | XX | ZZ | ZZ | ZZ | YY | ZZ | ZZ | ZZ | ZZ |
548+ +--------+----+----+-----+----+-----+-----+------+----+-----+
549+ | iOS 13 | | ZZ | ZZ | ZZ | YY | ZZ | ZZ | ZZ | ZZ |
550+ +--------+----+----+-----+----+-----+-----+------+----+-----+
551+ | iOS 14 | | ZZ | ZZ | ZZ | YY | s2 | s2 | s2 | s2 |
552+ +--------+----+----+-----+----+-----+-----+------+----+-----+
553+ | iOS 15 | | ZZ | ZZ | ZZ | YY | s2 | s2 | s2 | s2 |
554+ +--------+----+----+-----+----+-----+-----+------+----+-----+
555+ | iOS 16 | | ZZ | | ZZ | YY | s2 | s2 | s2 | s2 |
556+ +--------+----+----+-----+----+-----+-----+------+----+-----+
557+ | iOS 17 | | ZZ | | | | s2 | s2 | s2 | |
558+ +--------+----+----+-----+----+-----+-----+------+----+-----+
559+
560+ We start by looking for these two instructions:
561+
562+ +---------------------+
563+ | lsr xN , xN , 0xc |
564+ | stur wN , [ xM , - 0xc ] |
565+ +---------------------+
566+
567+ Where N < 16 and M >= 16 .
568+
569+ In r2:
570+
571+ /x 00fc4cd300421fb8:10feffff10feffff
572+
573+ After th at , we search for a "str wT, [xM]" (same base register , offset 0 ) within 20 instructions.
574+ We expect one of the two following sequences there:
575+
576+ +----------------+
577+ | str wT , [ xM ] |
578+ | ldr wS , [ xM ] |
579+ | tbz wS , 0 , ... |
580+ +----------------+
581+ | str wT , [ xM ] |
582+ | bl ... |
583+ | ldr wS , [ xM ] |
584+ | tbz wS , 0 , ... |
585+ +----------------+
586+
587+ Where S < 16 .
588+
589+ Right after th at , devices with TZ1 have another block with the same base register but offset 4 :
590+
591+ +-----------------+
592+ | str wT , [ xM , 4 ] |
593+ | ldr wS , [ xM , 4 ] |
594+ | tbz wS , 0 , ... |
595+ +-----------------+
596+ | str wT , [ xM , 4 ] |
597+ | bl ... |
598+ | ldr wS , [ xM , 4 ] |
599+ | tbz wS , 0 , ... |
600+ +-----------------+
601+
602+ Again with S < 16 .
603+
604+ We NOP out the str , ldr and tbz in both blocks.
605+
606+ * /
607+
608+ sym antitrust
609+ mov x2 , x0 // instr
610+ mov w7 , 0xfffffe10
611+ mov w8 , 0xd34c0000 // lsr xN , xN , 0xc
612+ movk w8 , 0xfc00
613+ mov w9 , 0xb81f0000 // stur wN , [ xM , - 0xc ]
614+ movk w9 , 0x4200
615+ // Search for pattern
616+ 1 :
617+ ldr w3 , [ x2 ], 0x4
618+ and w4 , w3 , w7
619+ cmp w4 , w8
620+ b.ne 1b
621+
622+ bfi w9 , w3 , 0 , 5
623+ ldr w3 , [ x2 ]
624+ and w4 , w3 , 0xfffffe1f
625+ cmp w4 , w9
626+ b.ne 1b
627+
628+ // Search for "str wT, [xM]"
629+ and w7 , w3 , 0x3e0
630+ movk w7 , 0xb900 , lsl 16 // str wT , [ xM ]
631+ add x3 , x2 , 0x50
632+ 2 :
633+ ldr w5 , [ x2 , 0x4 ] !
634+ and w4 , w5 , 0xffffffe0
635+ cmp w4 , w7
636+ b.eq 3f
637+ cmp x2 , x3
638+ b.lo 2b
639+ b . // XXX: fail
640+
641+ 3 :
642+ // Patch 1st write
643+ mov w10 , 0xd5030000 // nop
644+ movk w10 , 0x201f
645+ str w10 , [ x2 ]
646+
647+ // Check for bl
648+ ldr w3 , [ x2 , 0x4 ] !
649+ ubfx w4 , w3 , 26 , 6
650+ cmp w4 , 0x25 // bl
651+ b.ne 4f
652+ ldr w3 , [ x2 , 0x4 ] !
653+
654+ 4 :
655+ // 1s load
656+ orr w7 , w7 , 0x00400000 // str to ldr
657+ and w4 , w3 , 0xfffffff0
658+ cmp w4 , w7
659+ b.ne . // XXX: fail
660+ // Patch 1st load
661+ str w10 , [ x2 ]
662+
663+ // 1s tbz
664+ mov w8 , 0x36000000 // tbz wS , 0 , ...
665+ bfi w8 , w3 , 0 , 5
666+ ldr w3 , [ x2 , 0x4 ] !
667+ and w3 , w3 , 0xfffc001f
668+ cmp w3 , w8
669+ b.ne . // XXX: fail
670+ // Patch 1st tbz
671+ str w10 , [ x2 ]
672+
673+ // Check for 2nd set of str , ldr , tbz
674+ orr w5 , w5 , 0x400 // [ xM ] to [ xM , 4 ]
675+ ldr w3 , [ x2 , 0x4 ] !
676+ cmp w3 , w5
677+ b.ne Ligma
678+ // Patch 2nd write
679+ str w10 , [ x2 ]
680+
681+ // Check for bl
682+ ldr w3 , [ x2 , 0x4 ] !
683+ ubfx w4 , w3 , 26 , 6
684+ cmp w4 , 0x25 // bl
685+ b.ne 5f
686+ ldr w3 , [ x2 , 0x4 ] !
687+
688+ 5 :
689+ // 2nd load
690+ orr w7 , w7 , 0x400 // [ xM ] to [ xM , 4 ]
691+ and w4 , w3 , 0xfffffff0
692+ cmp w4 , w7
693+ b.ne . // XXX: fail
694+ // Patch
695+ str w10 , [ x2 ]
696+
697+ // 2nd tbz
698+ bfi w8 , w3 , 0 , 5
699+ ldr w3 , [ x2 , 0x4 ] !
700+ and w3 , w3 , 0xfffc001f
701+ cmp w3 , w8
702+ b.ne . // XXX: fail
703+ // Patch
704+ str w10 , [ x2 ]
705+
706+ Ligma:
707+ ret
0 commit comments