All righty.
So here we are back on our Ubuntu VM and now let's do this exercise together.
So what we want to do is the following.
We want to hook this function, this row dice function and we want to print out these two parameters
every time this function gets called.
So every time we press this button, these parameters, these values of these parameters should be printed
out into our terminal in the free console.
All righty.
We do not know how to do this right now, but we will learn it in this video.
And so we will do the step by step and we will also keep adding more stuff into this.
But this is regarding to other sections.
In this one over here, we only focus on printing out these parameter values in our terminal.
Alrighty.
And the next one, we will learn how to modify and manipulate them.
Okay.
But for now, let's keep it to just printing them out.
All right.
So what we need is we need our our blank page over here.
So we are opening Visual Studio code and now we are creating a new JavaScript file.
So we go into a new file and then I select over here JavaScript.
All right.
The first thing we need to do is we need to tell Frida that we're operating on an Android system and
we want to attach to the Java virtual machine because the Java virtual machine is having the reference
to these classes.
And this is the point where we need to hook into and modify them.
We can do this by simply using the function Java, perform this one over here.
So this is just a function call and this will attach to the Java virtual machine.
And let me close this real quick because it's a little bit annoying.
Okay, so this is our function and within this function we are now providing in parameter, which is
an anonymous function.
So we are having a function as in parameter in there and therefore we create a new function and this
is our body.
All right.
So this is our Java to perform function and this is our parameter right now.
All right.
And this is the place where we need to insert our code right now.
Okay.
What do we need to do?
The first thing is we need to get the reference to this class.
Which class?
Let's have a look.
Maybe.
Let's put the side by side.
Yeah, I guess it's a little bit easier to follow then.
And there we go.
Okay.
The class is public class, DYSON And we need to get the whole reference to this class because we can
have multiple classes with this name.
Therefore, we also need to have this complete package name in there.
We can get the reference to this class with java use.
So sorry I keep this in foreground.
Okay.
So we are using java to use and now we are providing this whole package name.
And this one.
DOT And then also the class name over here.
All right.
And this one we want to store in a variable and we name this variable, for example, my dicer.
Okay, so now we are having a variable, my Dyson, which is in reference to this class over here,
to this Dyson class.
All righty.
Maybe let's also write this down and get a reference in my Dyson of the class.
DYSON Next, we want to override the method.
And the method we want to override is this roll dice method.
So therefore, we need to use our reference to access this method and we can do this in the following
way.
My Dyson This is now a reference to this class and therefore we can simply use DOT to access this method.
In this case, it's called roll dice.
And now we want to define a new implementation for this for this method over here.
So we use dot implementation equals and here we are now defining a new function.
Again, it's an anonymous function and this is now the code or the place where we need to insert our
code that overwrites this function.
Okay, so what do we want to do?
We want to print out those parameters.
All right, but how can we access these parameters?
Let's have a look.
We are having two parameters right now.
One integer pool size, one integer phase none.
So regarding to JavaScript, we are also having some types in there.
For example, we are having boolean string and integers, but it's not like in Java that we need to
precisely define this.
This is automatically being adjusted and this is also the bad side about JavaScript.
So we will have a lot of trouble regarding to these types later on, but we will learn how to deal with
this one.
In this case right now, regarding to those basic types, for example, strings or integers, it's very
easy for us right now.
All we need to do is we simply need to provide these parameters in our anonymous function over here,
and then we can access them.
So for example, here we can write parameter one, and here we can write parameter two.
We do not have to define the same names or what type it is right now if we are dealing with integers
or strings.
Later on we will learn how we can provide more precise parameters.
For example, if we are having an object in whole class that needs to be provided over here, then we
need to do it a little bit different.
But regarding two basic parameters, we can stick to this approach over here.
Parameter one and parameter two.
All right.
Now we can simply access them so we can write, send, and then, for example, parameter one is equals.
And then we simply append this over here.
Parameter one So this typecasting will happen automatically.
This is good at the beginning, but it will become worse later on.
So if we are having more complex functions, we want to hook or providing new objects in there.
This can be a little bit painful, but for now we are happy that it's that easy right now.
All right.
So this is parameter one.
And then we also provide parameter to.
Plus Parenthood.
All right.
This is all we need to do right now, right?
Absolutely.
This is not all we need to do right now, because what we are doing right now, if we having this script
in this way, we are overriding this function.
And this is something I would like to explain to you on the graphic tablet.
We will see what happens if we keep the script in this way.
But this will not work.
I will show you why.
Okay.
So here we are back on the graphic tablet.
And now let me show what this script is doing right now.
So we are hooking into the dissect class and this one over here into roll dice.
And now we are overwriting this function.
We are still having our parameter over here.
This is param one and this one is param too.
But now we have overridden this function in the following way and this line does not exist anymore.
So this is completely gone.
Also this for loop is completely gone.
And also the return value is completely gone and this is now a big problem.
The first problem is that we do not get back our values.
So this function is not returning any dices anymore.
So there is no dice being returned.
This is not happening anymore in dysfunction because we have overwritten it with this stuff.
But dysfunction is doing right now.
It's taking those two parameters in this one and it's printing them out.
Print per on one and also print param to.
And this one over here.
Beside having no functionality in there anymore.
We are also having another problem.
The function is returning an integer array and this one over here and this one will be used in the function
call and it's expected to have some value in there because this function will always return a value
because we cannot select, for example, zero dices.
That's not possible in the application regarding to the interface.
Regarding to freedom, this is possible so we could override this function to have zero dices in there,
which means we are returning back and empty array.
So we are returning back null or we are not even returning something back.
However, so this function is definitely not returning the correct values, which means the program
is relying on those values and will use them later on.
But now these values are not being initialized or are just empty.
Therefore, if the program or the application and this one over here, our app tries to access these
values, right now it's getting a null pointer exception and it crashes.
So this is the state we are having right now.
I mean, we have achieved our task so far that we are printing out these parameters, but the application
doesn't work anymore and this is something we definitely want to have.
Nevertheless, let's try this out at this stage right now and see what happens.
All righty.
Okay.
Therefore, we can use a real device.
Or in my case, I will also demonstrate this on the virtual machine, because this application works
on the virtual machine.
I mean, we do not have to slip directory regarding to external resources, but this application also
doesn't have NLP directory in there, so it doesn't have shared object files in there.
This means this application is not platform dependent and it should work on the virtual machine.
All righty.
Okay, so let's clear this up.
Let's close this one over here.
And now we can save the script and save as we can save it or store it in the app directory.
So within apps, where do we have it?
Privacy friendly design.
Here we can now, for example, name this param hook trace so we can use the script in freedom directly
or we can simply use the command line interface of freedom.
I will show you both ways right now.
Therefore, we have to set free the app first.
So we need to connect to our between the machine.
We need to start a free the server and then we need to connect to this free server.
Okay, let's see.
ADB shell.
Do we have a connection?
No.
Then let's see if we can establish an connection.
ADB Connect.
Connect it.
All right now adb shell.
Then we need root privileges.
And then within data, local temp here be having our free de server.
In my case, I have to.
I guess I use the 32 bit version in case if this does not work, I simply switch to the 64 bit version
and afterwards I clean it up that I know which version is the correct one for our freedom over here.
So we start with the 32 bit version.
The free server has now been started and this means if you opening a new terminal and using free that
dash as dash you, which means get the information by the existing ADB connection of the processes running
on the smartphone, then we can see okay and Free De is working so far now we need to attach to this
process.
So I'm opening a new one and keep this in foreground.
Here we are having this process still running this one over here and now we want to attach to this process.
Let's see how we can do this.
The thing we need is the package name and we get this from the Android manifest.
And this one over here.
So this application will be identified by this package name.
And this is also the way that Frieda, the way Frieda uses this to identify this application.
So we want to look with Frieda via the ADB connection into this process.
All right.
Seems to work.
We are having our Frieda console.
And no errors right now.
Now, let's also keep this in foreground.
Okay.
We, we first make sure that the application still works.
So by clicking raw dyes, yes, we can see it's the working and it's also working correctly, I guess
because we are getting back random values.
Maybe let's switch to five.
Yes.
Okay.
Looks fine right now.
Now we take this whole script so we copy, paste everything in here and we insert it over here.
Okay.
So this looks a little bit messy, but it works directly if you press enter so you do not have to adjust
anything.
Medical.
We have now applied our script to this to this Frida instance, which means Frida has hooked into the
Java virtual machine and has now overwritten this function in there.
This means if you are using this function in our application, we are now calling our modified version.
Let's see what happens if we click Roll Dice.
The application did crash and let's go upwards and let's see so we can see.
Maybe let's make this a bit larger.
So we can see we are having our two messages.
So we can see parameter one must be number five and parameter two was the number six absolutely perfect.
This was correct.
But then we've got this error over here, error implementation for roll dice expected a return value
for compatible with.
And here we are having our integer error rate.
We notice right now from our smiley path.
All right.
Freida is amazing, helpful if it comes to errors.
So Frieda tells us, well, I have hooked into parameter one and I have printed it out over here and
then I have also hooked parameter to and printed it out over here.
But this function expects an integer array and you do not return anything.
Right now you have overwritten this method, but you are not returning something back over here.
Therefore we are getting a node pointer exception and we completely crash.
Okay, so how can we fix this issue?
Well, it depends, of course, on what we are trying to achieve in our case right now.
All we want to do is we want to hook into this method.
We want to print out these parameters, and then we want to have the original method being called.
Do you remember how we can do this?
Of course.
Yes, absolutely right.
We need to call the original method and that's all.
And we can call the original method in the following way.
This roll dice and here we have it.
If we tried this right now, we still fail.
The reason for this is we are now calling the original method without any parameters.
This would be like having this method over here.
Not this one.
This one, without having any parameter in there.
The application will still crash because it tries to initialize new arrays and fill them.
But we do not provide anything right here.
Nevertheless, let's try this and see how free the response.
So we need to start this application once again because it has been crashed.
There we go.
It works, probably.
Regarding to our Freedom server, this one is still running.
All we need to do is we need to connect to this application process once again.
We are now connected, make this a little bit larger.
And now we take our new script.
In this one and we apply it over here.
Okay.
Don't worry about this.
Pop up over here.
Just hit enter after you have copy.
Pasted it in here.
All right.
So now we are calling the original method.
But we did forget about the parameters.
We did this on purpose.
And let's see how Frieda responds.
So if you opening up this application once again and hit roll dice, then we can see it crashes once
again.
So let's see.
What's this time?
The error.
And here we have roll dice.
Argument types do not match any of overload into it.
We will come back to this overload in in a further section.
So we are not dealing with this right now.
Okay.
Beside this overload tank over here, we can see this function expects two parameters, these two integer
parameters, and we can see we are having argument types do not match any of.
So this can be the case in two scenarios.
The first one is we are providing the wrong number of arguments.
And for example, or in this example we are providing no argument or no parameter.
And this is not compatible with this function over here.
The upper case would be we are providing the wrong types of parameters in there, and this one is a
little bit more tricky.
And it's also regarding to this overload.
We will learn how to do this in a further section.
For now we know, okay, we have not provided any parameter in there.
So our problem right now is regarding to the amount of parameters we are providing to this function,
which is zero.
If we go back here, we can see we are not providing anything.
So what we need to do is simply passing through the parameters from here back to the original function.
Then this original function gets called with the correct parameters that has been also inserted into
this function before.
All right.
So in parameter one and parameter two.
Okay.
So what have you done right now?
We have hooked the following class.
We made this a class, and we have defined a new implementation for this method.
Now we say, print out those two parameters you're providing to this function.
We are doing this over here.
And then we also need to call the original function that this one over here is returning.
An integer array in this function requires two parameters and we are taking the original parameters,
these two, and passing them simply through this function over here.
All right.
So let's see right now, if this one works, therefore, we have to restart this application once again.
Here we have it.
Let's see how this one works.
Now we are using our our free the command line to attach to this process.
Once again, we paste in this code, we hit enter and now let's see if it works.
Roll dice.
And we still get an error.
What?
Why is it that complicated?
The reason for this is right now we are not returning anything.
So we are just calling this function.
But we are not using this in return statement.
So let's figure out what we have done so far and why it's still not working.
The first thing we have done is we have overridden this whole method over here.
So this one has been completely erased.
And we have overwritten this part with just some print statements regarding to these two parameters.
Then we have figured out, okay, this function over here is returning an integer array, an integer
array, and this one is being used in the application code.
So if you are not returning this array.
If this is not the case, then we encounter an exception.
Therefore, the temptation for me right now was let's simply call the original method, and then this
should return our integer array over here.
Therefore, if we go back to our script, this one over here, we have called the original method over
here once again.
So this one should now return our byte array.
And this one over here.
And everything should work, right.
I mean, we have also figured out that we need to provide these two parameters to the original method.
Call over here.
So these two.
Why is it still throwing error?
The reason for this is and this is our free test script in this one over here.
Let's write this down here.
And now we have overridden this method.
This was the first step.
But then we have also called the original method, which is this right now.
And this is step two.
The thing is, this method gets called.
So Frieda is calling the original method over here.
And this one is simply just returning back to freedom.
But we are not doing anything with this return value over here.
So this one is returning back, this integer array.
But we need to pass it also into our function over here.
So here we are calling this function.
We are calling this original method function.
And this one and this one is returning back our return value, which is the integer array.
But we are not doing anything with this one.
What we need to do is we can start this in a very able over here so we can assign a new variable or
we can simply return this whole statement over here so we can simply write.
Maybe.
Let me clean this up real quick.
There we go.
So we could simply right return.
This original method call.
And what this one does is, is the following we're having here our freedom script.
This one is now calling the original method.
In this method original, this method is now returning back this integer array, and this one will be
now returned in freedom.
So this is this statement over here, this integer array.
And then it should work.
I know this is a little bit overengineered regarding to the explanation, but if we do not consider
all the stuff, we will run into trouble and we will wonder why things do not work.
Therefore, I will keep this very detailed explained on what's happening over here.
And yeah, sorry if I borrow you on this point and if you're already familiar with Frieda, but it's
very important that we know everything what's going on over here and why things are not working anymore.
All righty.
Okay, so now let's get back and apply this little patch that this one over here finally works.
Let's go.
Okay, so here we are back.
Let's clean the screen and there we go.
Okay.
And what we need to do is we simply need to append this return statement.
Now we are calling this original method and we are passing through the return value of the original
method into our freedom method over here.
This should work right now.
Let's see.
And that's opening this application and seems to hang.
Therefore, let's simply restart it.
Here we have it once again.
And let's see if this application is still being opened.
Here we have it.
Okay.
It's restarting because it crashed before.
Let's see, it's working now.
Let's get our free the terminal.
Where do we have it?
The one in red with all these error messages.
We need to connect to this process once again.
We apply our script.
We hit enter.
And now let's see.
Roll the dice.
There we go.
We can see this one.
Here is the function is still working, even by pressing it multiple times.
And we can see parameter one is five and parameter two is six.
So let's see if we change them over here.
Yes, we can see those changes also affect our debug output over here.
So this is freaking amazing and extremely helpful.
I use this quite a lot regarding to password functions and cryptographic functions.
For example, we are having an A's implementation and the function gets as an input in initialization
vector and the key and those two values we need to decrypt or encrypt and message or this package or
whatever we have encrypted over here by simply hooking into the AZ implementation, we can simply print
out the values that's being passed to this function.
I mean, in this case we simply just have to integer values, but we can also have an initialization
vector.
And yeah, the key that's being used to decrypt and encrypt this stuff.
This whole setup takes just a few minutes.
If we have already identified this function, which is responsible for this one, and then yeah, we
have all the necessary stuff to decrypt or encrypt these messages.
We will have some examples later on.
But for now, before I get to hype up right now, we need to get to some basics first.
All right.
Okay.
So this is how we can work in function parameter and print it out regarding to the whole concept over
here and also the explanation why things have not worked the proper way.
I think you can imagine how we can manipulate this right now.
So this is the task for you in the next section, manipulating these parameters instead of using them
from the from the original application.
Let's adjust our own parameters that no matter what selected over here, the number of dices or number
of faces, we are overwriting this with our own static values.
So, for example, to be a little bit more precise on this one, let's say our challenge is to always
return for thisis between the numbers one and three.
So this is the challenge for thisis numbers one and three, no matter what I select over here.
All righty.
All right.
So this is the task for the next challenge in case if you struggle a little bit, don't worry.
We'll do this together in the next one.
And I'm really looking forward to see you there.