 So, hi, I'm Jeff and I have a problem. I like to do bad things to worse programming languages and for the purpose of this talk, that means Java. Thank you. So I'm going to, right before I get into this, I do want to say that this is really like a 40‑minute talk distilled into 20 minutes. So I have a lot more material in the slides than I'm specifically covering. I go through it really fast and I recommend going through the slides on their own at some other point since they have a lot of gems hidden in them. But so, getting back to it, what does this talk about and why does it matter? This talk is about injecting JRuby and Android applications to do function hooking and this might be useful to you if you reverse Android apps or if you develop them, it's just another debugging tool, honestly. Or if you have some strange fascination with Ruby and or repels. So, going back in time a little bit, I was reversing this chat app called line that's really screwy. And aside from the pro guarding and stuff, which doesn't really matter, the main annoying part of it was that everything was like an interface of something else and it was really annoying to find out what objects actually were at run time and I was just writing a bunch of one‑off hooks to like see what the object was and then go off and do it again. And this was getting real boring real fast. So, I decided, you know, what if we took all the interesting functions and wrap them in repels, you know, so you drop down like a shell and you just kind of poke around at run time and see what things are and see what they have inside them all ad hoc style so you don't have to like write some code and then run it and write some code and run it all over and over and again. So, to take a step back a little bit, let's talk about kind of what the things you can do on Android right now are. So, you can use LD preload, it's pretty old school, native hooking with native code for native functions, you know, things like libc calls and stuff. I'm kind of skipping code as I go. I recommend going through my slides, as I said. Then, of course, there's actually using the debugger which is basically the JDWP that you have in the normal JVM, ADB exposes it and there are various ways of getting into it, either being an API debuggable or, you know, you have written stuff. The useful things from it are that it can list all active instances of objects, of all Java objects and when you set break points, you can actually execute code in them from the context of the frame where the break point got hit. So you can hit, like, you can touch, like, protected stuff and private variables that can be hit by the code normally. It slows down the app massively, though, like, almost the point of being unusable. But it is useful for things. There's a lot of GUI stuff, a lot of GUI stuff, it's all terrible and even the command line stuff for it is basically toxic. You hit up and you get this horrible, like, A character thing because it doesn't handle, like, arrow keys. But it works. Moving on, we have Frida, which is sort of the new hotness for a while. It works on Android. It actually stomps over the actual instructions in memory to, you know, jump to its own hooks. It also recently has the capability to inspect and list all the active Java objects so you can just tap one specific object. The function hooks are generally speaking implemented in JavaScript which is not something I like, but it works for many people and if you don't want to do that, you can use the native C slash G-lib code, Frida gum to do hooking with anything that compiles down, like, you know, native code. There are many ways to get it working. But the hooks are fairly simple. Then, of course, we have Xygote, which is the, sorry, exposed, which is the kind of big main framework for doing function hooking on Android, which actually modifies Xygote's sort of in it process that forks into the actual apps. And the really nice thing about it is that aside from being like Java first or Dalvik first, which means you just write stuff that actually kind of has native reflection access into the code you're hooking, the other cool thing is that it hooks like always at the start of app start reliably, even early in boot. And so you can get very reliable hooks running without missing them by accident. It has a lot, a lot, a lot of scaffolding. But eventually you get to something like this where it's more or less the same thing as the JavaScript code. So now I have a question for you. Who's that Pokemon? Yeah, that's right. No, that's wrong. Sorry. Parasect. Parasect was right. So why am I talking about Pokemon in my talk? So Parasect is a mushroom Pokemon. And if you didn't know, the mushroom part on top of it is actually the Pokemon. The bug is a dead husk kind of marry netted by the mushroom at this point. The dead white milky eyes are sort of a hint. So again, why am I talking about this? So I wrote a tool called Paraspector. And it carries basically all of the same roots as Parasect does for the puns and things, plus what I got from introspection. And we get this cute little guy. So what is it actually, though? Paraspector is a function method hooking tool for Android focused on Java. It injects a full J Ruby interpreter into a target process so that the hooks that you run are J Ruby. They're easily reloaded every time you restart the app as opposed to exposed where every time you change the code, you have to reboot the phone itself. It's implemented using exposed, but of course the Java part doesn't change when you change your hook. And it has a bunch of selectors that you can configure based on classes and methods. Such as super classes or interfaces that are actually implemented by a class. It will just figure it out at run time. And if you don't want to pay the searching cost, you can just hard code the name of the class in. So if you just want to figure out what you want to hook, you can use these and then you can hard code it later so that subsequent runs are much faster. Not that they're much slower in general. Method matching uses the method name, the argument type signature, the return type, and the exception signature. And then whatever the total set of those combined, it'll find it or you can be as vague as you want. If you want to just hook two string on object, anything that subclasses object, you're going to get a lot of stuff. Ruby, or J Ruby really specifically is pretty useful in this case, much better than Ruby was when I attempted it the first time. It has very good interop with the Java parts. There are only a few cases where you have to do a little bit of reflection to get around some of the annoying pro guard stuff, but in general it doesn't really matter. The really useful thing with the way that I loaded in is that I loaded under the class loader that is actually for the app itself. So it has native access to load classes from the app without reflection. Whereas with exposed, you would have to use a lot of reflection to manipulate things. The other cool thing is that because of this, you can actually define your own subclasses and interface implementers for the Java code of the actual app itself and then plug them in any functions that like take a callback function basically. But I kind of started this conversation with Rapples and now I'm getting back to it now eventually. I use this thing called pry, which is a much better Rapple than IRB, the default one that comes with Ruby which also didn't really want to speak well over the network. And it's got a whole bunch of Ruby stuff that allows you to introspect the sort of Ruby still runtime, but also the Java one because of JRuby, much better than IRB, whatever. I use this thing called pry remote, which is a gem that kind of wraps pry with this crazy, crazy thing called DRuby, which is basically Corba for Ruby. And if you know what Corba is, you're shaking or throwing up, please, please do it in an empty seat next to you. It has no authentication by its own, which is scary because basically, without even like using this to send strings to eval, it basically is a dual eval between the client and the server in any direction, apparently. So it's super scary and doesn't have authentication. So I modified it, at least the one I install on the phone to add authentication. And then for the one you run locally, I have an authenticating proxy I wrote to sort of speak to that so that at least other apps can't compromise the one that you're actually hooking when you're hooking it. Then you drop down into basically with some connect back, a Tmux window that just pops up with your shell and things work. For apps that don't actually have the internet permission, this needs networking and so I have a bunch of hooks in using exposed that will basically force the internet permission in apps that don't request it. They really don't like that, but I get it to work anyway. For configuring all this monstrosity, I actually have a Jetty Servlet web app. I actually run from the device itself, which was an exercise in frustration. But it works. And all the edits that you make are actually tracked in a Git repo on device. So if you really screw something up bad, you can always like ADB pull that off the device and revert back to what you need to. It's also worth mentioning that that has authentication as well that works decently enough. But overall the flow is pretty simple. You edit config files, they're world readable so that the hooks that run within the context of the app you're hooking can read them. Then I set up the JRuby environment and then I iterate through the classes to do the searching and selecting and stuff. And then exposed actually I used to set up the actual hook. And then that hook runs your Ruby code. This is kind of what a hook looks like. It's kind of quick and dirty. We hook this method in this class and then we just kind of print out what the argument is and move on. But for anything more involved, you'll use something like this where you actually have a file that you can also edit through the web interface which looks like this. And this guy disables cert validation, cert pinning and also hard codes my HDP proxy so all the requests made using OKHDP go through my proxy even though normally speaking ignore the system proxy setting and like the Wi-Fi setting. You'd think this would be slow but I cheat really, really hard wherever I can. So I try to load as much of the JRuby in at Zygote in it. And because of that I do it I have to play some reflection dark magic so I can force in the class loader of the app to be the parent of the JRuby class loader so that the classes resolve correctly through the app instead of just up to the default set of classes in Android that Zygote can see. Due to some bugs in Android I can't actually set up a whole container instance that runs the scripts in Zygote because if Zygote takes too long to start up the whole thing deadlocks. I'd like to see it get fixed. So I have to start up the containers actually in the app itself and this takes like 6-7 seconds generally but I try to paralyze it out so it's not observable until a hook actually runs and then it'll have to actually finish before the hook will run. For the class searching and stuff because the normal like class loader searching stuff actually searches the parent class loader first before it searches the child I yank out the internal the dex classes stuff on Android using reflection and then I run that and that saves a ton of time. There's still this problem with basically the threading so there's this the class loader lock you can't actually load a class between it'll lock when you try to load a class and so the more threads you have the slower it goes. So I eventually I might start parsing the dex files manually but I'm not at that point yet because I haven't hit that as a performance roadblock yet. So I've been searching 30 seconds of overhead to being quote-unquote instantaneous which means if you hit that 6 to 7 seconds you have to pay for it. Searching is fast enough unless you hit something like the Facebook app which literally has 100,000 classes in it as of the last time I checked and because of the threading thing that takes a while to go through about 30 seconds. But this is still a lot faster than exposed stuff which you write your Java code you compile it install it and then you have to reboot the phone and wait like two minutes for the whole thing to finish if the phone is encrypted. So let's do some demos shall we? Let's hope the demo gods are with us. So I have this phone you can see on the screen. Let's do some math shall we? What's a good number? Answer your life, the universe and everything. So let's get there shall we? Oh what's that? That's not supposed to happen I think that apparently we have a new answer. So moving on to what that was I have this hook and hopefully it's seeable from the screen without too much of the flashing giving people epileptic seizures but basically I have this weird method in the pro guarded code it has this horrible function signature but it returns a string. The string it returns is actually the result of the calculation within the code and then when the value is something I like I do something entirely different. Moving on I have this UI demo where basically I have a bunch of buttons and you click the buttons and they do stuff and this is bad if you've ever seen Yu-Gi-Oh abridged you know that that last button is wrong let's do that one more time. That's what I'm talking about. So the hook on this is basically just on the text view stuff in the UI and I actually when I see this hello duelist string I completely replace the on click listener associated with the button so the event handler for the button I replace with my own implementation that subclass is the on click listener class that is what it actually needs as an interface to pass it to. So this one is now when I hit the button the first and then the second time actually jumps straight into my code no hooks anymore. So moving on now this is fine and good and all let's tweet. What's this? This is a shell. Who are you? Main activity. Let's just do some math for me. 10. I'm in the shell right now this is all sorts of things. This is the pry. But let's tweet. Does anyone have any requests? I know I'm asking a weird question to a weird crowd. Anyone want me to tweet something? Anything. Okay. And now we're back in the app and I actually I need internet. That's super important actually. Let's see if that worked. I'll do it again. Nope. So we'll do one more time. I have the on resume method hooked and so every time it goes back to main activity it'll jump back in my hook. There we go. Okay back here. Let's see if it did something. Yeah okay that one worked. Okay cool networking. How does it work? So this hook is a little interesting. Let me skip past. These are the proxy ones before from the slides. This one is a little interesting because the code for this I actually just made my own method that does a whole bunch of horrible reflection and stuff into the insides of the Twitter app and I figured out what the functions to call for their rest APIs are internally that actually do the tweeting. But whatever it works. One interesting thing is that I do the load class with reflection if only because there's this a field here which is a static when you have a static internal class that matches a static field with the pro guarding you sort of have to do this because the resolution order takes the field first and not the class. But where can you get this magical tool? The installation stuff I want to clean up just a little bit. There's no way I'm getting around having to reinstall it twice because of the thing with the internet permission. It actually sets up a hook for itself so that it can grant permissions itself but that requires you to reinstall it so that the second install the hook runs on the package manager that then allows it to take the permission. So only it can take the permission that it needs to grant permissions and only it can be used when you're in lockdown. Limitations, the DRuby stuff is super scary that's probably going to be its own talk since it's super dangerous. Adding gems not quite supported yet requires some shenanigans I'll probably get around to that soon. So the stuff with the gems I might make a UI to do it fancier it might just make it easier to do in the build process. The UI could use just a little bit of work maybe. Android 7 compatibility isn't there yet because exposed doesn't support it yet. If and when it does that's what I have to fix. If it doesn't, I have some plans on how I can stop using exposed but I'd prefer to use it because it's useful for a whole bunch of stuff. I'd like to thank a whole bunch of people specifically Arcos, the Scorpion writer aka Josie, our former intern who I basically sacrificed to this thing is a lot for QA work. She wasn't able to make it out here today but thank you Josie. Are there any questions? Oh, you want to know? Yeah, of course. So, Ruby has this wonderful thing it's a stringer place. So if we go search for maybe not our favorite president but A president I mean someone's favorite he apparently is a fan. Any other questions? Was that a no? That wasn't a question? Okay, anyone else? No? Okay, thank you everyone.