Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VP9 entitlement spoofing does not work on jailed environment #8

Open
PoomSmart opened this issue Dec 18, 2021 · 17 comments
Open

VP9 entitlement spoofing does not work on jailed environment #8

PoomSmart opened this issue Dec 18, 2021 · 17 comments

Comments

@PoomSmart
Copy link
Owner

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.

@mihir-io
Copy link

Based on your wording, does this mean that even H.264 on <= 1080p videos is using software decoding if YouTube is sideloaded?

@PoomSmart
Copy link
Owner Author

@mihir-io H.264 isn't affected.

@BionicBison05
Copy link

Any progress on this? Or is it simply not possible?

@level3tjg
Copy link

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

@PoomSmart
Copy link
Owner Author

@level3tjg Curious if there are any existing sample projects out there.

@level3tjg
Copy link

@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.

@PoomSmart PoomSmart pinned this issue May 18, 2022
@level3tjg
Copy link

Calling FigServer_Initialize() at any point before a decoder instance is created will skip the VP9 entitlement checks, however video playback still returns AVErrorDecoderNotFound.

@PoomSmart
Copy link
Owner Author

Well it is still tricky to bypass VP9 checks from inside YouTube app because the function is unnamed.

image

@level3tjg
Copy link

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.

VTIsHardwareDecodeSupported

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.

@PoomSmart
Copy link
Owner Author

@level3tjg Interesting. Can you maybe share the code about FigServer_Initialize so I may try on my own devices?

@level3tjg
Copy link

FigServer_Initialize writes to gIsMediaserverd and FigServer_IsServerProcess reads it, that's all.

image

@PoomSmart
Copy link
Owner Author

@level3tjg So how do you get the symbol for FigServer_Initialize ? dlsym ? MSFindSymbol ?

@level3tjg
Copy link

@PoomSmart I linked against CoreMedia and declared it as an external function

@PoomSmart
Copy link
Owner Author

@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.

image

@level3tjg
Copy link

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.

@PoomSmart
Copy link
Owner Author

I see. That probably means you tested hooking entitlement check function directly too.

@level3tjg
Copy link

There are additional entitlement checks performed by FigVideoQueueRemoteServer_Create within mediaserverd 🙁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants