VP9 entitlement spoofing does not work on jailed environment
PoomSmart opened this issue ยท 17 comments
The technique relies on MSHookFunction()
which does nothing on sideloaded apps. As a result, no hardware decoder has ever worked on sidedloaded YouTube. We may be able to use fishhook instead.
Based on your wording, does this mean that even H.264 on <= 1080p videos is using software decoding if YouTube is sideloaded?
Any progress on this? Or is it simply not possible?
According to dyld source it is possible to replace functions in the shared cache with closures, not sure if it's possible to implement without a jailbreak though. Might be worth looking into
@level3tjg Curious if there are any existing sample projects out there.
@level3tjg Curious if there are any existing sample projects out there.
Turns out plain interposing (storing interposing tuples in __DATA,__interpose) should actually generate a closure with the correct patch entries, however it only applies patches to the cache from the main executable's closure and when I tried it didn't seem to work. Fugu14 exploited a bug in dyld to pre-generate a closure to inject code into some processes but it looks like it was patched in 14.7
From Closure.h:
Dyld cache patching notes:
The dyld cache needs to be patched to support interposing and dylib "roots".
For cached dylibs overrides:
Closure build time:
1) LoadedImages will contain the new dylib, so all symbol look ups
will naturally find new impl. Only dyld cache needs special help.
2) LoadedImages entry will have flag for images that override cache.
3) When setting Closure attributes, if flag is set, builder will
iterate PatchableExport entries in Image* from cache and create
a PatchEntry for each.
Runtime:
1) [lib]dyld will iterate PatchEntry in closure and patch cache
For interposing:
Closure build time:
1) After Images built, if __interpose section(s) exist, builder will
build InterposingTuple entries for closure
2) For being-built closure and launch closure, apply any InterposingTuple
to modify Image fixups before Image finalized.
3) Builder will find PatchableExport entry that matchs stock Impl
and add PatchEntry to closure for it.
Runtime:
1) When closure is loaded (launch or dlopen) PatchEntries are
applied (exactly once) to whole cache.
2) For each DlopenClosure loaded, any InterposeTuples in *launch* closure
are applied to all new images in new DlopenClosure.
For weak-def coalesing:
Closure build time:
1) weak_bind entries are turned into -3 ordinal lookup which search through images
in load order for first def (like flat). This fixups up all images not in cache.
2) When processing -3 ordinals, it continues past first found and if any images
past it are in dyld cache and export that same symbol, a PatchEntry is added to
closure to fix up all cached uses of that symbol.
3) If a weak_bind has strong bit set (no fixup, just def), all images from the dyld
cache are checked to see if the export that symbol, if so, a PatchEntry is added
to the closure.
Runtime:
1) When closure is loaded (launch or dlopen) PatchEntries are
applied (exactly once) to whole cache.
Calling FigServer_Initialize()
at any point before a decoder instance is created will skip the VP9 entitlement checks, however video playback still returns AVErrorDecoderNotFound
.
It should pass YT checks since VTIsHardwareDecodeSupported
will return true for VP9. FigServer_Initialize
sets a flag in CoreMedia that says it's running inside mediaserverd, skipping the entitlement check.
If VTSelectAndCreateVideoDecoderInstance
succeeds then all of the checks pass and a decoder instance is created and added to VT's decoder registry. I've verified that VP9 is in the decoder registry so I'm not sure why I'm seeing AVErrorDecoderNotFound
in the YT player.
@level3tjg Interesting. Can you maybe share the code about FigServer_Initialize
so I may try on my own devices?
@level3tjg So how do you get the symbol for FigServer_Initialize
? dlsym
? MSFindSymbol
?
@PoomSmart I linked against CoreMedia and declared it as an external function
@level3tjg I believe your trick introduces a side effect when VP9 decompression session is being created from YouTube app - it won't communicate to mediaserverd
correctly anymore.
I don't think that's the case, even if you bypass the entitlement check by other means (with a jailbreak but sideloaded app) you'll still get the same outcome.
I see. That probably means you tested hooking entitlement check function directly too.
There are additional entitlement checks performed by FigVideoQueueRemoteServer_Create
within mediaserverd ๐