19.11.2016 Views

Technical Analysis of the Pegasus Exploits on iOS

eNQc3Ry

eNQc3Ry

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Within OSUnserializeBinary, a while loop iterates through each encoded object within <str<strong>on</strong>g>the</str<strong>on</strong>g><br />

supplied data blob. The loop begins by determining <str<strong>on</strong>g>the</str<strong>on</strong>g> type <str<strong>on</strong>g>of</str<strong>on</strong>g> object (e.g.,<br />

kOSSerializeDicti<strong>on</strong>ary, kOSSerializeArray, kOSSerializeNumber, and so <strong>on</strong>) and<br />

its size.<br />

len = (key & kOSSerializeDataMask);<br />

...<br />

switch (kOSSerializeTypeMask & key)<br />

{<br />

case kOSSerializeDicti<strong>on</strong>ary:<br />

o = newDict = OSDicti<strong>on</strong>ary::withCapacity(len);<br />

newCollect = (len != 0);<br />

break;<br />

case kOSSerializeArray:<br />

o = newArray = OSArray::withCapacity(len);<br />

newCollect = (len != 0);<br />

break;<br />

case kOSSerializeSet:<br />

o = newSet = OSSet::withCapacity(len);<br />

newCollect = (len != 0);<br />

...<br />

case kOSSerializeObject:<br />

if (len >= objsIdx) break;<br />

o = objsArray[len];<br />

o->retain();<br />

isRef = true;<br />

break;<br />

...<br />

}<br />

The switch statement dispatches <str<strong>on</strong>g>the</str<strong>on</strong>g> appropriate instructi<strong>on</strong>s for handling each type <str<strong>on</strong>g>of</str<strong>on</strong>g> object<br />

found within <str<strong>on</strong>g>the</str<strong>on</strong>g> data blob. These instructi<strong>on</strong>s can generate new objects and set flags related to<br />

<str<strong>on</strong>g>the</str<strong>on</strong>g> objects depending <strong>on</strong> what <str<strong>on</strong>g>the</str<strong>on</strong>g> particular object requires during <str<strong>on</strong>g>the</str<strong>on</strong>g> deserializati<strong>on</strong> process.<br />

The kOSSerializeObject object type is a special case that represents an already<br />

deserialized object and, as such, sets a flag isRef to true indicating that <str<strong>on</strong>g>the</str<strong>on</strong>g> object is a<br />

reference to an existing object already within <str<strong>on</strong>g>the</str<strong>on</strong>g> objsArray array.<br />

If <str<strong>on</strong>g>the</str<strong>on</strong>g> isRef value is not set to true, <str<strong>on</strong>g>the</str<strong>on</strong>g> current object that just underwent deserializati<strong>on</strong> is<br />

added to <str<strong>on</strong>g>the</str<strong>on</strong>g> objsArray by means <str<strong>on</strong>g>of</str<strong>on</strong>g> setAtIndex:<br />

if (!isRef)<br />

{<br />

setAtIndex(objs, objsIdx, o);<br />

if (!ok) break;<br />

objsIdx++;<br />

}<br />

setAtIndex is a macro that, am<strong>on</strong>g o<str<strong>on</strong>g>the</str<strong>on</strong>g>r things, adds an object (o) to <str<strong>on</strong>g>the</str<strong>on</strong>g> objsArray. While<br />

more robust array objects exist within <str<strong>on</strong>g>the</str<strong>on</strong>g> <strong>iOS</strong> envir<strong>on</strong>ment, such as OSArray (an array<br />

c<strong>on</strong>tainer that will handle reference counting automatically), OSUnserializeBinary takes a<br />

more manual route for array-object management <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> objects it has deserialized. Once<br />

Page 26

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!