httptoolkit / frida-interception-and-unpinning

Frida scripts to directly MitM all HTTPS traffic from a target mobile application
https://httptoolkit.com/android/
GNU Affero General Public License v3.0
905 stars 178 forks source link

Fix #6 #12

Closed londek closed 1 year ago

londek commented 2 years ago

Change SSLContext_init.call(this, keyManager, TrustManagers, secureRandom); to this.init(keyManager, TrustManagers, secureRandom);

Clearly the method is not static and so it should be called from it's instance, maybe I am missing some inner forbidden knowledge, but this.init is proper way to call instance method

londek commented 2 years ago

Looks like it was just a temporary fix? But still, good to replace

pimterry commented 2 years ago

Hi @Londek. Thanks for checking on this, but I think the current code is correct! It's important to understand how this works. For reference I think the code you're talking about is this:

https://github.com/httptoolkit/frida-android-unpinning/blob/91422adeda7982e32d761e7efe6ac95286eb8254/frida-script.js#L126-L135

The issue is that the second part here replaces the init() method on SSLContext. That means if you call this.init(...) inside that method then I think you'd actually be calling the same method defined here again, and you'll get an infinite loop and a stack overflow.

SSLContext_init meanwhile is a reference to the original instance method, before it's replaced. By calling .call(this) we are calling it with an instance - it's not being called as a static method. This will be an unusual pattern coming from Java, where this is always implicit, but manually providing this to an instance method is a useful trick that's available in JavaScript, Python and a few other languages.

This works because of how the JVM works internally: static class methods and instance methods are actually defined exactly the same in the bytecode of the class, the only difference is on how they're called elsewhere (i.e. because the function caller will provide a this parameter). From Frida, we can call any static or instance method we like with or without a this parameter, and instance methods will just fail if they try to use this when one wasn't provided. We're in the guts of the JVM here, and none of the normal rules apply :smile:.

Does that make sense?

Are you having an issue with the current implementation in your setup, or was this just something you noticed out of interest? Happy to help investigate if there's something specific that's not working for you.