There are at least two major architectural differences between software and hardware versions affected by this WebKit bug (it's quite old, probably iOS 10 and 11 at least):


1. Gigacage mitigations: Before the introduction of Gigacage, the exploit would
	 have been entirely vanilla: The bug trivially provides `addrof`/`fakeobj`
	 primitives, and thus we could have used the standard `JSObject` misalignment
	 technique from http://phrack.org/papers/attacking_javascript_engines.html
	 (section 6.2) to forge a Float64Array and gain arbitrary R/W directly. This
	 does not work anymore with Gigacage, hence we use a slightly different
	 fake object. But on older software it might be advisable to fall back to 
         saelo's technique.
2. Spectre mitigations: Introduced sometime towards the beginning of 2018, they
	 add certain fields to JSObjects and might influence some of the offsets that
	 the exploit uses, for example `var fake_addr = stage1.addrof(outer) + 0x20`
	 will probably be `+ 0x18` on some older versions. Also, the structure spray at 
	 https://github.com/phoenhex/files/blob/master/exploits/ios-11.3.1/pwn_i8.js#L109 
	 is designed to place a large value right before the monitor object (as a fake `vectorLength`), 
	 but with smaller `sizeof(JSObject)`, the number of inline properties might have to be 
	 increased/decresed by one here.
3. JIT hardening: iPhone 8/X use a new JIT mitigation using
	 `os_thread_self_restrict_rwx_to_{rw,rx}` (see ExecutableAllocator.{h,cpp} in
	 WebKit). The WebKit exploit as well as the Mach-O loader assume
	 that this is the JIT hardening used. However, other devices, even on 11.3.1
	 probably use the old JIT hardening as described in https://www.youtube.com/watch?time_continue=200&v=BLGFriOKz6U. 
   The exploit would probably notice this on 11.3.1 because `useFastPermisionsJITCopy` 
   is 0 in this case. If that's the case, we can use `jitWriteSeparateHeapsFunction` to 
   achieve the same memcpy primitive that we currently use `performJITMemcpy` for.
