 all right welcome um you're currently in meticulously modern mobile manipulations and if that's a bit of a mouthful you can just say hmmm. All right um today I want to cover some uh cases for a little bit more advanced mobile application hacking um we'll look at some use cases for freedom and uh see if we can figure out how we would go about improving our current tooling and improve it in a way that would make it relevant for us going for from today going forward and um yeah let's see how that goes. First of all my name is Leon Jacobs I'm a security researcher at a company called Saints Post back in South Africa um it does not get as hot as this but uh we'll leave that aside for now and I've been hacking stuff for roughly around 10 years now. I have been fortunate enough to play around on large networks at ISPs and maybe a little bit more complicated ones at banks. Now part of my day job at the moment sometimes requires me to perform mobile application assessments and to be pretty honest with it I've hated that pretty much a lot. So I've set out to see what can I do to go and improve the state of mobile application hacking and really just make it a way that it sucks a lot less for me. Now how we're going to go about that today we're going to try and see with these three phones that are clearly IOAS 13 ready um I don't know a serious note uh we're gonna cover a bunch of techniques but they're primarily targeted at three uh disciplines from a mobile hacking perspective. The first scenario or discipline would be that of a mobile application hacker that wants to poke around and maybe understand how such an application works. The second discipline would be one that uh speaks to a mo- uh malware reversal that maybe needs to understand quickly how a mobile application functions or what it's doing uh right now. The third scenario is sort of targeted more towards those that are responsible for some development pipeline and might be involved in the CI CD pipeline to deliver some form of testing. Now these uh techniques that you'll see here is probably about two years of work that I've been doing um on and off and uh ultimately the results of it should be shown now. That being said before we can actually get to that stuff we probably need to have a bit of a sit down and understand where we're at right now as if a parent is going to give us a stern warning. The reality of uh mobile app hacking today is I think we're sort of bearing the fruits of the research of many of those that might have done in this room where mobile ecosystems are so tightly controlled, they're relatively complex um beasts in themselves that it's quite hard to do a mobile app pentest right now. In fact there are so many moving parts of this thing that I'm pretty sure you'll groan very loudly when you realize you need to do a mobile app pentest. That being said um things get even a little bit more complicated if we consider the state of jail breaks. While you may be fortunate enough to have access to commercial products that could give you um route access to the latest operating systems or maybe you have a private jail break that you don't want to share which is fine. For the general populace with iOS 13 available in beta today where we don't have a public jail break, chances are good that when that becomes the latest and greatest OS and an application is written that makes use of NFC APIs what are we as mobile app pentest is going to do about um when a client asks us well you're now need to go and look at what that application is doing. Secondly um the result of this testing of these tight ecosystems also means that we can't really understand what's really happening with the apps. If we had to consider scenarios maybe where big data is watching us and uh we not certain that if we're downloading a flashlight application which I might ask why you want to do that today um is it actually just a flashlight application or is there different alternative motives to why we have this app in the first place. In fact how do we get to a point where we can understand how this data that might be used in an application is used against us for monetary purposes or other reasons. This sort of I believe forces us to try and reshape how we think about uh mobile app hacking and look at alternative methods to approach this. One such method could be using a uh framework or a toolkit called Frida. The reality of Frida is I sometimes find it hard to truly explain what it really does um other than saying it's a toolkit written by Ole Andre and honestly I sometimes can't believe why this is actually free. The capabilities of Frida spans far beyond what you might see today uh but we'll just focus on the mobile application aspect of this. But maybe before we can understand how that is actually gonna help us as app pen testers let's look at a very quick analogy. In this case we have a castle or a fortress and imagine that this castle is the mobile application app that you need to test or you want to look at how this thing functions. With root access to your device you can move around in this castle, you can see what's happening inside, you can open any doors and you're truly free to inspect any of or any aspect of this uh fortress. However when you don't have a jailbreak well now you're sitting on the outside and it's pretty dark in the inside and you have no idea what's really going on over there. You're not allowed in, you're not allowed to move to a castle next door and the restrictions applicable to us are quite uh severe. However if we had to take and combine that with Frida we can sort of see it as if this gives us the opportunity to have this light to move inside of that castle and uh again be in a place where we can see what's going on around us. Now this man here doesn't have much other than a torch but uh the reality is it's a starting point for you to be able to explore and investigate a runtime of what might be happening um around you. Now to actually understand the implementation of this and to leave the metaphor aside um we need to get Frida going on a device. Now there are two primary operating modes um that may be of interest. One would be a server mode and that's really targeted at if you already have roots on your device then you can run Frida without much restriction. I'm sorry everything you would see today is applicable in server mode but we're going to focus specifically on the gadget mode. Now I must be really honest this gadget mode excites me a lot especially the first time when I realized what this is possible to do. Are we going to look at a little bit of that again today? Now an important part of how would I get gadget mode going? Well you're going to have to modify target application. There are some small nuances uh applicable when considering iOS but the idea is still the same. For Android you might take a small little bit of Smiley and you would patch an application to load the shared library which is the form that the gadget mode would take and when an application starts up that gadget is started as well. A similar scenario applies for iOS in which case we'll modify an application to load the dial up and again get us the instrumentation capabilities that we might need. Now if we had to move on and consider well what might Frida be used for today and we take the scientific results from two Google poems we could see that uh if you started typing Frida iOS the results could give us an idea of what folks might be searching for. SSL pending bypasses, root bypasses really are pretty common usages for Frida. And make no mistake this is a super powerful tool for doing that and um leveraging these techniques I think is something that we can take a lot further. Maybe if we can try and understand the underlying technique of how these things work we could maybe move along and see what else we can do. Now imagine you had a pending class with a check pin method. Using Frida we actually have access to the implementation of that method. So what does that really mean? Well when it's time for check pin to run we now have access to the entry point to that function. We have access to the logic of what that function is actually doing. And finally and probably more applicable to an SSL pending bypass we have access to the return value that that function gives us back. So you now understand how an SSL pending bypass works considering that maybe the implementation simply returns a true or a false we could use the implementation to modify exactly that. Now that is really useful thing to do and like I've mentioned um something that will probably not go away for a very long time and that we have in our OSL right now. But we can absolutely do a lot more. In fact I think we had one scenario where uh we had to do an assessment. The app does not run on a device that we have a jailbreak for. But part of this assessment meant that we needed to get access to a file inside of that application's container but without a jailbreak. Now a little bit of thinking and considering a little bit later I realized that while when we are doing hooking we can manipulate existing logic that is within our application we can actually also go and introduce new logic. And when I'm saying new logic I'm actually just saying that there is a class available for us to use in the runtime and we can instantiate a fresh instance of that class. Now Frito makes this super easy for us to do by simply running some of or using some of the APIs that Frito exposes. The first of all would be the Java use case and which case we're just instantiating a new instance of Java IO dot file here. For objective C environments there might be a class called SI files and in this case we're simply instantiating uh sorry allocating and initializing that class. Now when we're just initializing these classes we now actually have a variable that we can call the methods applicable to that class um ourselves. In fact if we start combining these things we're in a scenario where we can actually start building some extra tools which might result in us uh extending functionality that's not necessarily part of that original application that we are testing. Now in our case remember the part where we needed to get access to a file inside of a container it's exactly this thing that happened. In fact I started writing a bunch of scripts which resulted in a toolkit that I wrote called objection which um in its infant stages was actually just a file manager using exactly the same building blocks that a developer would have used if they wanted to build a file manager and uh add some capability to list files within a containers directory and ultimately download those out again. Now a file manager is uh interesting uh scenario so let's have a quick look at what that might look like. In uh this video's case I hope it's this one there we go um you should see an existing session for objection running already and there was um uh file interactions that happened you know you could see these through to the directories within the container and uh inspect what the contents of the file system might be. Now applicable to this demo one quick little bit of um information that you might need to understand is if you're using an iOS app and you had to back around the app iOS will take a screenshot of that application's current state and this is to make it nice if you're using the app switcher to know what the last states of that app might have been. Using the file manager that we've built we can uh go to that directory and uh see what the co- what those files are and quite possibly download them as well. So in this case over here using a relatively familiar interface uh we go to the snapshots directory that contains these files and uh if we had to hit the alays here we'll see the files themselves. Now like I've mentioned we could do something like just downloading this file and inspecting what it might be. But what if we started thinking about what else we can uh uh extend our app with? In this case we're actually going to consider adding an HTTP server to the target application which I should have mentioned is YouTube over here and this would actually start the HTTP server on my iPad allowing me to browse to the iPad's IP address and view that same directory listing from a web browser. More importantly this is not functionality that exists in this application out of the box. We've used instrumentation to augment what uh we wanted to add to it and build our tooling on from there. Alright. Now as you may have seen this really really opened a lot of uh possibilities for us. In fact furiously we're at a stage where we're building new tools, porting older ones. For example imagine the old keychain dumper which many of us are probably familiar with. From an outside rooted jailbroken perspective that keychain dumper really just interfaces with the SQLite database on iOS. But within an application container if we wanted to build a keychain dumper we can actually just port that same logic and have it contained within the container and still be able to understand what's being stored when I'm instrument or when I'm using this application at runtime. Now one thing that might be interesting or that could help understand how all of this fits together is the super exploratory uh explanatory picture that would link, you should see the little line over there, um all of these uh components together. First of all you would have the javascript runtime um that Frito exposes for us that we could use um to write some scripts. But that won't be the starting point if you wanted to write a new tool. In fact you would probably target the objective C runtime if you wanted to write your keychain dumper. But to make use of this from a Frito perspective once we have some valid uh objective C running we can now port that over to the javascript runtime and that's what the little link should show um and run it from there. The exact same process applies when we're speaking of a java runtime or even if you wanted to run some native code. Stringing all of these um runtimes together is ultimately what gives us that ability to um work with these runtimes and build fresh new tooling. But okay let's shift gears a little bit and consider application heaps. When we're speaking of an application heap over here really what I'm saying is uh we have a class we've instantiated an instance of that class and that would live on a heap for a certain amount of time. That instance itself has methods that gets called from it and whatever the reason is and why we have this it might affect some states of the application. Now a lot of the research that you'll see over here hinges over ex colleagues work that was done Chris Leroy that um explored the idea of using java objects that live on the heap to possibly identify some forms of malware and try and understand how that works. But for us and what I've hoped to try to take this further is to see well what else can we do with this stuff. If we're considering application heaps maybe the first thing that we need to understand is what type of classes that are on the heap could be interesting. A list as you might see there could be things that handle cryptography in some way that might make socket connections out on the internet. Um maybe handle some states for the target application. There might be some configuration set for your app or if in an android world there might be a class loader that loads some classes from the outside. If we understand maybe what classes might be interesting maybe if we zone in very quickly of what we might want to do with such a class it could look something like this. Methods could exist on a class that could get instead properties. A class itself there's properties which has some values. And understanding what those values are could actually tell us what the state of that class is right now. But more importantly if we are calling methods on that class we might actually be changing the state of that class that is as it is right now as the application is running. Now a lot of the stuff might seem a little complicated but from a freedom perspective we really have two APIs that start exposing the stuff to us. We could simply use the Java dot choose runtime um sorry the Java dot choose API. And that would actually just enumerate us instances of a target class that we might want to interact with. Similarly in the objective sea world again the choose API would do the same thing. But that's not a lot of talk. Let's consider what a uh this might look like and the way we could use this. What you should see over here is um once the video loads is um there's a terminal on the left hand side and where we're going to interact using objection. And on the right hand side there's a video that's looping from uh uh tick the tick tock application. Now this application itself um I spent a little bit of time reversing it just to understand what it looks like. And I've identified one class of interest that seems to be controlling the current video that's playing right now. Now using that choose API wraps over here from an objections perspective we can actually enumerate live instances of that class like I've mentioned that uh we might want to interact with right now. The outputs of the commander just ran gives us three instances that we might want to work with. We could copy one of those which has a uh which is a pointer to that class and I'll start interrogating it to understand more about it. One way we might want to do that is to actually tell it show me the instance variables that we have for this specific class that lives at that pointer. The answer that we get back is actually a bunch of information which includes all of the properties for that class including some values that it could easily read. You'll see many of these are actually handles to more comp- more uh classes. So what we can try and do now is to try to cast those to UTF-8 strings which should result in much more uh information about what this class is doing what its current state might be. And in other words actually what the current video might be that is playing. Now understanding what's inside of the class we might choose uh a different route and maybe see which methods do we have exposed to us by purely interrogating that actual class itself. By doing a heap print methods um command we should get a list of methods that we can run on this class instance that's on the heap right now and maybe see that there's a play command and a pause command. And these are the type of things that we might use to interact with uh the video that's currently playing at the back. Now like I've mentioned we might want to change the state of this thing. So to do such a thing we could actually just go and execute that method that we have found for this instance and uh if we hit the pause method over here we should see the video pause um using the interaction that we've just done. Naturally to continue you could just go and call the play method once again. Now in this case we've had two method calls that didn't accept any arguments. They're really simple calls, they don't do a lot really interesting. So let's consider other methods that might be a little bit more complicated. One such method that you would find in that list would be sent content URL string and you would see it except one argument. Now uh from a freedom perspective you can write a separate script or from objection perspective you could get a new command that will show in a second that will actually give you a JavaScript variable to the address that that pointer points to. So if we do the evaluate method here it will tell you that the PTR variable is actually just a variable that binds to that um address on the eep and uh we can now work with it. Now in this case I actually want to change this video to a little bit more educational one. So I have found a URL for such a video on YouTube and uh I now want to change TikTok without interacting with it to play that video uh as we have it. So we've identified set content URL string so we're going to call that method on that PTR variable again which is just a pointer to the object and give it the URL argument that we um wanted to to load. The next thing that you would find if you were to reverse this app a bit there would be a prepare to play method and all this really does is just downloads it in the background and gets it ready to display um in the foreground. Now next thing we might want to do with this little script is to actually set uh or give ourselves a bit of a visual indicator that that was successful right? So the only thing we'll do then is just log that we're done and uh wrapping all of that up run the script itself. When the script runs you see in the background that the app itself is now just gone dark. So the next thing you might want to do is just to ask you to actually play that. So like we've already been doing we'll just call that play method on top of it and we'll enjoy some recreational content that may um inspire you to do this yourself. Awesome. Okay. But I think the point to take from here is using simply one address I'm also sure this is the most most of us have seen of the video before you just close it. Um but an important takeaway from this is you've enumerated an instance of an object uh we've manipulated it by pausing and playing and we've actually changed its state by setting a variable and uh making sure that that loads up giving us a nice visual indicator that something has changed. Now all of that was iOS specific stuff so let's uh consider um Android. Well exactly like you've seen over here is actually applicable to Android as well and from an objection perspective the interaction is pretty much the same. Again in the underneath it uses the same APIs that we've been using for iOS so it is really not a lot different over here. However if we had to look at one example for Android very quickly um we could take the YouTube app and ask it show me the instances of the next class loader that are live right now. What's quite nice about the Java runtime it has a two string method on many classes so we could actually very quickly see what that um uh methods properties might be or at least some of the properties that the uh class might have. Okay. Now we've noticed that there's a .APK I promise I didn't name it that and uh now that we know where it might live, we have a part, we could probably just go about and use the file manager that we already have and download that for further analysis later. Again this doesn't require you to have root, you just need to modify the app to get the gadget going and you could quickly get to um some content that you might not have known initially from static analysis. Now while on that topic what about applications that we're unsure of what they're actually doing or ones that you're relatively certain is probably malware. Well obviously you could perform some static analysis, reverse the app, see what it's going on underneath the hood um and get a good idea of what it might be ha- what it might be doing. However at the same time that could be a pretty tedious task and depending on um how the app is built it might not be a very easy thing to do. In fact it's not really a secret to know that apps might actually try and hide their true intent. Well malware apps for that. Interesting techniques like using a packer or some really heavy obfuscation might make it difficult for you to understand from a static analysis perspective what an application is truly up to. Um if you don't have a lot of time and you maybe want to collect some IOCs very quickly again you know a static analysis approach might be a little bit tricky. One method a lot of apps might use to uh try and make this a little bit difficult is to actually use reflection. By using reflection they could programmatically make calls to methods and uh you know depending on what the source of that logic might be the method calls themselves are not immediately um known. However from a runtime perspective we could actually have this uh exact same method hooked and as they're using reflection to uh invoke calls we could use that to understand what the calls themselves are. Now one such um piece of malware was something that we had a look at that uh would load a JAR file actually out of a bitmap and uh once the JAR file is loaded use reflection to call methods that's on top of that. We have a sample hook here that I want to show you very quickly that uh does exactly that hooking the reflection methods to understand what the app is doing. The one thing I would need to do is apologize for the speed of this I've actually slowed it down quite a bit. But um we're running a malware application here in a Android emulator there's no way I'm installing that stuff on an actual phone. Some of it is really really dodgy. But um by hooking the invoke method for reflection we can actually see all of the calls and possibly some of the arguments that are being used to um make these uh interactions that the malware is supposed to be doing. Now like I've said this is slowed down quite a bit. You don't have to worry about actually following on all of that. But towards the end we should start seeing some socket classes making network connections out to the internet. So we can quickly deduce at this point that there's probably something strange going on here or at the very least there's some network activity that we might want to have a look at. Now once we've inspected maybe some of the network activity maybe we want to try and understand how this application actually came to uh make this logic happen in the first place. Well one such thing like I've mentioned the next class loader could be used to load arbitrary um code from outside of what you may have expected it to come from. And we can see over here that using reflection the class loader was loaded and it actually tried to load that jar file that you can see in the past over there. More interestingly though once that jar was loaded it actually deleted off disk using a delete call later you know and making it a little bit harder for you possibly to catch that and actually uncovering what this malware might be up to in the first place. Alright. So I hope that sort of gives you an idea of how that might work. But what about existing tools? What about tooling that developers are using to augment their development experience or uh making their lives a lot easier? I truly believe as security professionals we're probably missing out by not leveraging the exact same tooling that they might be using as well. In fact some of that stuff I've seen I can't believe that is free and you can actually use it yourself as well. Anyways, one way if we had to use uh instrumentation is we can actually side load this existing tooling into an application that um doesn't have it and make use of exactly the same features a developer would do. We can leverage an API from Frida if it came in the form of a shared library using simply module dot load and pointing it to a pass on disk within the application's container to a shared library that might have the debug tooling that you're interested um and use that. Now shared libraries are not the only form in which these things can come. In fact you could also have a Java tool obviously for Android uh and you can side load that much like malware probably would do it but uh allowing you to leverage the same features that they might have. I want to look at two examples relatively quickly today of each one would be uh Flex from Flipboard which targets iOS and another would be the Stessout project from Facebook. Both of these tools are uh tools that developers can use that absolutely augments their uh development experience and probably more so the debugging experience that they might um or scenarios that they might need to debug. The first would be Flex and I'll load this um and you should see over here just was that that on the left hand side we have the terminal with some interactions from objection and on the right hand side I have the YouTube app that's just connected with QuickTime to the Mac. There is a plug-ins flag that you're probably seeing for the first time now and that was a community contributed feature that uh allowed us to just full side load Frida scripts quickly with an objection. However the most important thing really to understand from that is it's just Frida script at the bottom and there's nothing really different about it. Anyways if we decided that we wanted to load this Flex plugin we could run a command like plugin flex load and all this will do is using that file manager that objection originally had to upload the shared library into a directory finally call module dot load which will result in this little debug bar popping up in the YouTube application. Now I can tell you that YouTube app doesn't have Flex by default but we've now just side loaded Flex and made it possible for us to use it just like a developer would do to understand what this application might be up to and make use of any of the features Flex has uh you know for us. One thing it has a really cool network uh inspector so I would highly encourage you to have a look at that as well. Alright now uh from an Android perspective like I've mentioned we have Stetho as an example and in this case um for Stetho specifically sorry I just need to get this proper demo. Um let's take a little bit of a longer route around this and understand what's happening. We have a shell on the left hand side, an Android app that's stripping to my phone uh to my laptop and a Chrome inspector at the bottom. I've launched the reddit app and uh I'm just quickly going to interact with it as if I am normally using this application. I'll go to my favorite subreddit um read a little bit of news and probably get bored of that pretty quickly. With an objection though at this point I might be interested in which activities are available within the runtime right now. Now at runtime you can query Android's packet manager and that could give us a list of activities that is um targetable right now. If I had to go through the list of activities that I've enumerated one such activity might catch your eye called the data logging activity. Well data logging seems interesting so let's go and build a fresh intent um again using Java to run via JavaScript to launch the actual intent but wrapped up in an easy command like you'd see here which should result in that activity actually launching on the Android app and letting us use it. In this case over here though you should see quite a lot of um tracking related logs and if you go into the detail of some of this stuff um it's a little bit hair raising really to see why they need to know what the current theme is as part of your um browsing experience. But okay we can keep that in mind on the side. Now I might decide that at this stage maybe I want to use stethos features to browse data on the device itself. Much like the flex scenario we can just load stetho up using a plugin and that should result in a class loader being used to actually instantiate the classes in a jar and finally call the initialization method that it has. Once that's done the way stetho works it has a um inspector that you can use at the bottom and if you'd inspect that it's just a normal chrome inspector that actually gives you access to the files within that container. So preferences files in this case or SQLite databases that you might have access to as well. Over here we might notice the period db and in that case see events relatively similar to those that we saw in the data logging activity itself. Now what's possible here is you can run raw SQL queries on that data and what you should keep in mind is if you have an application that actually has some states stored within a SQLite database changing the data in that database might actually affect the states of the application that you're targeting. Maybe there's a key in there that you could update to something else or you know let your imagination go pretty wild. Alright. Now what about integration? Um if we had uh when I had this this thought about you know how could I make it that we can integrate to things uh it seems like a very difficult thing but when I had a bit of a thought about it I realized like a lot of the building blocks on how to do this actually already existed. Now when I do speak of integration you know from my perspective it's really just HTTP requests into something that would give me some results back. If we had to consider an architecture of what that might have looked like we already have the Frida um gadgets involved somewhere in an application. We already have a bunch of parts and tooling written around it. So really the only thing that was necessary was to expose an HTTP server from which an HTTP client would be able to connect to serializing messages using JSON. In fact this resulted in really just three lines of code. You can check me on that um to get it to work. So that was like quite surprising and easy to get going. However the result of that would mean we could now make a call request and using runtime instrumentation go and figure out for example the binary protections that an iOS app has. This is just one of the many scripts that exist in Objection and make some decisions based on that if we require them to be enabled or not or maybe even question their existence in the first place. Now just being able to use call commands might be um interesting but we could probably actually add this to a Jenkins pipeline. So if we had to look at what that might look like. I have a project over here that um is configured using Jenkins. There is a uh the configuration of the project is actually quite simple. The first step would be to just build the app that I have and this app has the gadget embedded. The next step is just some simulator commands to actually get an iOS simulator running, installing the app that just got built. Once that's done we would start up Objection which will give us that opportunity to interact with the Frida gadget using HTTP messages. And finally the actual checks that we want to make to make sure that certain protections are enabled and uh that we fail if they don't. Finally just some cleanup scripts to save space on my limited hard drive. Alright now we'll probably go into the build phase and uh although this is a little bit small to see the details are not too important. This will now just go through that entire phase of actually building a project, modifying the simulator uh and getting to a point where the Objection API is actually listening. And that's what you should see over here in a sec. Once that's up and going the again this is now an app that's actually running in the simulator. At runtime we are querying to see what are the binary protections of the final artifact that we've had um on the uh device. This is that binary that's probably gonna be the one that's gonna get shipped to your end client. Because my project is configured in such a way that has all of these protections enabled um my build completes and I'm now at a state where I can continue with whatever the next step might be. So I'm hoping that gives you an idea of probably many other use cases where if you're concerned of what the last final stage of your app is you could use instrumentation in an automated fashion to query that runtime and assert certain features that you might need. Alright so let's really quickly recap about what we've just said. We're saying that um apps are you know at a runtime for many disciplines might be it might be interesting for us to query that uh this is applicable for hackers, this is applicable for malware reverses and even those folks that might be responsible for a CICD pipeline. Some of these techniques that you've seen today absolutely overlap for some of these disciplines but uh the general idea is that it would enable us to improve the actual testing that we're doing and we're not relying on all tooling that might not be working on a non-gel broken device. So to summarize all of that um I would love for us to realize that you know runtime analysis is more than just hooking it's much more than just SSL pinning bypasses although absolutely powerful we have the ability to build many more tools and extend our arsenal that we have. We don't always need routes to run these types of things which means that if I was 13 for example had to drop today we still can't test and we can still do a proper analysis of how these applications might work. Finally irrespective of what your discipline is um anyone can use this it's applicable to many folks involved in some form of mobile application pipeline and uh as a final stage we can use this for the greater good to actually understand what our apps are doing if our data is being shift off somewhere we can catch that and I think it's everyone's responsibility here to actually do that and I hope this encourages you to do that. Thank you. One final thing that I'd like to mention the stuff that you've seen here should be available in the release that I would make an objection as soon as I can get to a computer after this and yeah awesome.