Welcome back.
After hooking the NDDC functions the easy way.
Now let's have look into the hard way.
Exactly.
This one over here.
So we have to deal with tons of stuff.
If you want to look native function.
And to be honest, we do not get any advantage out of this one right now.
Nevertheless, we are doing this.
Why?
Because people later on deal with in function where all this knowledge right now becomes super handy.
All righty.
Okay.
So please see this as some kind of practicing for a challenge we are doing later on.
And therefore, let's figure out how we can who can function not in the Java world, within the C C++
word.
Let's go.
All right.
So here we are having our C C++ code.
And the first thing we need to do is we need to identify the function we want to hook.
I mean, we could have reverse engineer this application, but by doing this, we would miss a lot of
things.
For example, we do not get things like the function pointer or other stuff.
Therefore, we are using freedom because freedom has also the ability to enumerate all these functions
free.
The cannot only enumerate them free does also providing the function pointers for them.
So we get all the addresses of these functions over here and let's say we are interested in the following
in this one over here.
Then we can simply list all these addresses and then we can select the address that's related to this
one, to this function.
We want to hook this one over here having the address, that's all we need.
So we can now use our interceptor dot attach to attach to this address.
And this means we are observing everything that happens over here and here we are providing now our
two callbacks, our own enter and also our only callback.
The on enter callback will be called when we are entering this function within the on enter we are having
access to the parameters.
The only callback will be called and just right before we are returning out of this one, this means
we are still having access to the return value.
So this is directly before we leaving this function over here and therefore we can still observe the
return value and we can also apply a patch on this one so we could modify this one over here.
All right.
In total, it would look like the following over here.
So this is the summary of our interceptor dot attach we attach to this function pointer and every time
we are entering this function, we can apply our patches and every time we are leaving this function,
we can also apply our patches.
Alrighty.
Okay.
The only question that's left is the following.
How do we get these functions and all these addresses?
And Frieda has a lot of amazing capabilities to do this.
So my three favorites are the following module dot.
And then we can enumerate imports, exports and symbols.
We will have a look into each of them and we will also figure out what's the difference between them
on the graphic template later on.
For now, I would suggest let's simply start over here.
So we will make our way into this topic step by step.
Alrighty.
Okay, let's go.
Let's switch to the Ubuntu VM and let's see how we can hook a native function with Rita.
Let's go.
All right, so here we are back at Ubuntu VM and now let's have first a look into this application once
again.
So we get back this smartphone screen and here we can see this is our app.
If you hit oops, sorry if we hit the button then we can see it scripting in this text over here and
let's change this.
Frieda is awesome.
Well, let's see.
Yes, it's still working.
All right, now let's open this application with shady excluded and let's figure out the function and
we want to hook.
All righty.
Okay, so we close this one, then we open a new terminal and we go into apps and decay free to all
here name the differently free to indicate that we have it.
And now let's open this one.
Okay.
We go into the Android manifest.
And we click into the main activity.
All righty.
Let's see.
There we have it.
This one over here?
Yes.
Decrypt string.
So this is the method.
And so this is the method we want to look right now.
Therefore, let's fire up Frieda and let's have a look on how to enumerate this method with Frieda.
So we open a new terminal.
We are connecting to our device root privileges, and then we start up the Frieda server.
All righty.
Frida's running this on the right, this one in front.
Plus this one, and we put this on the left.
Now we attach just simply to this process.
So free the dash u and then com app hacking and this one is in d k freedom.
Now we are connected.
And so the first thing we need to do is we need to identify the address of this function over here,
decrypt string and we can do this in the following way.
So free to has this nice modular feature and if you click or enter module dot, then we get all these
methods that are available.
We've got one that is enumerate exports, imports and I guess symbols, enumerate symbols.
All right.
Now ask the question, where is the difference between all of them?
So what are imports?
What are exports and what are symbols?
Let's find this out right now.
We start with exports.
If you simply hit enter, then we can see this one is in function.
So we have to provide.
Yeah.
And function to this one.
So we need our brackets.
If we do it this way, then we can see it's expecting a string.
So over here, we need to tell Frida in which library it needs to look for all these exports, and this
library can be found.
And let's see.
Over here within lip, we have this little native dash lip as well.
So this is the library that we want to enumerate all these exports, because this is the library that's
being loaded over here as native lit.
And this is the library that contains our method.
Alrighty.
Okay.
So let's see enumerate exports and we have to enter.
Sorry, this on the right, we have to get this name.
Little native dash, lip dot.
So if we now click enter, then we can see.
Already we are getting back in array and this array has three entries for every function the address,
the name and the type.
So over here we can see it's not just related to functions, it's also related to variables.
And sorry for this wording.
This is regarding to all exports, not just functions or to variables.
Alrighty.
And let's see what we've got inside here.
So these are the exports and this list is huge, I guess.
Yes, we've got a lot of stuff in here, but if we scroll upwards, that's not.
Let's see.
There we have it.
So.
So let's go down a little bit.
Could.
Okay.
So the big.
Okay, so here we are at the beginning and now let's go down a little bit.
All right.
And here we already have it in CYBERCOM app hacking and freedom main activity decrypt string.
This is exactly the.
The function we want to hook.
Amazing.
So this one over here, that's the address.
Absolutely nice.
We are now having the address of this function.
We are now in that c enumerate exports.
So that's the difference between exports and imports.
And let's do this for the imports and maybe then it becomes a little bit more clear enumerate imports.
Yes.
So here we can see we print f free maps that man copy malloc we as printer memory string compare and
things like this.
So let's take a quick look on the graphic tablet and figure out what our inputs, exports and symbols
of this file over here of this native library.
Alrighty.
Okay, let's do this real quick.
Okay.
So here we are having our library and this one has been written in C or in C++.
Now let's assume we've got the following code line we've got in print f.
And we are printing out.
Hello.
I'm Frieda.
At the moment right now.
And this function over here is unknown to reprogram, and therefore, it will be flagged as red.
All right, if you want to use this out of the standard Lipsey, then we have to do the following.
We have to include.
The standout i o dot h file.
And so this standard i o header file will be included into our program over here in this one.
And now the program Noah's Ark.
This one that's the print function out of the standard I o header file.
Now I know this and this function won't be flicked red anymore.
So this means we are having here now our standard lib library and this is our standard lib c and this
one is now defining all these functions.
And for example, print, f, f, open and more.
So all these functions are being defined in this library and they can be now imported into our program.
And this means all this function over here, these are imports.
For our program right now.
So we are imparting these functions into our program.
Well, this one over here.
Alrighty.
Inputs therefore simply means function that are coming from a different library.
All right, then let's say we've got this one over here.
So we've got our decrypt string, and this one needs to be available outside of this library.
For example, in our Java code, therefore we need to export in this function to make it available in
another program.
So this one is now outside.
And so exporting simply means and taking a function that has been defined by us.
So this has been defined by us and make it available to the outside.
So if someone is including this file over here.
So this would be included.
Then this function is also available for this program right now.
All right.
So this would be an export in this one over here.
Okay.
Last but not least, we've got symbols and symbols are and functions or variables that has been defined
in our program.
And so functions or variables.
In our program that has not been exported to others or imported from others.
So this is just, for example, something like this string p w equals secret.
All right.
And this one over here, p w this would be in symbol.
By having those three right now, we can access everything we want.
For example, if you're looking for something that has been imported from another library, then we
can check the imports.
If you're looking for something that we are exporting to other libraries, then we can check the exports.
And if you're looking for something that has been defined in our code in this one, for example, then
we can look for symbols.
All right.
So now.
All right.
Okay, so this one over here.
This is the difference between imports functions into our program, exports and function out of our
program and symbols.
Stuff only available in our program over here.
Okay, so now we understand them and this will help us a lot in identifying what we are looking for.
Therefore, let's switch back to freedom.
Okay, so here we are back at Ubuntu Beam.
Now let's have a look into this one once again.
We've got mem set mem copy malloc.
Do you still remember if these are now exports or imports?
Of course you do.
These are imports.
And you might have already seen this over here.
These are being imported from the Lipsy dot, so.
All righty.
So if you're looking for methods like a string, copy, string, compare, mend, copy, mem, compare
and things like this, you have to look into the imports.
Perfect.
Now let's dive back into the exports.
So let's change this one over here.
And here we can see these are now all our exports in our library, in our native lib.
So if we go back to the top over here, so then we can see these are a lot and it's absolutely ridiculous
to find our method in there.
So if we scroll down, then we might identify it over here.
And here we are also having this address, this piece, what we are looking for.
But to be honest, this is not a good approach.
I do not want to search manually through all of this and therefore let's create a new file within our
Visual Studio code at the top, and then let's figure out how we can do this automatically.
Every time we are starting this application, let's fetch this address.
Alrighty, let's do this.
So we open up wizard studio code.
There we have it.
And this time we do not have our Java perform approach because we're not in the Java world anymore.
We have already figured out the command.
We want to use this one over here.
Maybe let's put this on the right and this one on the left.
I hit the upper hierarchy.
Then I get the last command.
This one over here.
This will return an array with all.
With all these values.
Address, name and type.
Let's copy this one.
And paste it in here.
Okay.
Now let's create a new array.
But before we do this, switch back to JavaScript.
Okay.
Now we are creating a new array and we name this export.
It's a little bit laggy on my side.
I guess I close.
And they screen copy
exploded and functions.
Yes.
If you're executing this one over here and then we have now this exported functions and this one is
an array that contains all this stuff.
We can use this to access one field, for example, this way, and then we can say, for example, address.
This is now the address of the first element.
We can also print out the name.
And by doing this, we can now look for our function.
So the function we are looking for is the script string.
Therefore we write an for each loop on our array.
Maybe let's comment this really quick.
Getting all x spots out of the loop.
Native dash lib as all.
Iterating over this array, trying to find decrypt the string so we can iterate over this one.
Let me put this on the right by default for each loop.
Yes.
This one is an array.
Therefore, we have this function.
So we've got two parameters an element, an index.
I'm not sure if we are using this index right now, but it's good to have.
Okay.
Now we can simply use our if statement.
So if element dot name and in JavaScript it's not contains it is I guess includes.
Yes.
If this keyboard is included.
So the keyboard which we are looking for is decrypt the string.
Then let's see, we want to print it out and we want to print out the element name.
Let's copy this.
The element not address.
And let's try if this one works.
Perfect.
We've got this with Vincent, which is not that nice.
We can also replace this with console.log.
Okay.
And that's the list once again.
There we have it.
And this is our name.
And this is the address.
Yes, the address should be right.
Okay.
Nice.
So now we can also create a new address.
Let's call this decrypt the string address.
Purpose of the function we want to hook.
No.
Let's make this a bit nicer.
So this is the name.
And to be having the pointer.
And now we are also filling this array.
Sorry, this array, this variable over here.
So this one is now element dot address.
Yeah.
Without a bracket.
Okay, this should work.
Let's do this one more time.
Already.
And this means decrypt in string address.
Here we have now our address.
Perfect.
We can now use this within our interceptor dot attach.
So this is the last blueprint, the third part of our free, the syntax we need to memorize.
And to be honest, it's pretty identical to Java to choose.
So instead of Java to choose, we are having interceptor dot attach.
And here we are having now our address, which is this one over here.
And then we've got one comma and we've got our callbacks.
All right.
These callbacks, double click, curly bracket and enter.
Exactly like we have done this in shape or choose.
Alrighty.
Now let's define them.
We've got our end on enter callback providing an anonymous function and this time we are only having
one argument and this is an array of arguments.
So this will be done automatically.
If we're having two elements, then we've got zero one.
If we are having five, then we've got zero to act four.
All right, so let's print this out and send.
We are in there we go, decrypt the string address and then we've got our on leave callback and same
approach.
And this one has also this time and parameter which is the return value.
I name this normally, right?
And we also printing out Mia leaving the decrypt string function right now.
Sorry for this one.
That's a bit confusing.
The script string.
Let's see if this is the correct name.
Yes.
All right.
And this is how we can enter and leaf and function or hooking the entering and leaving a function.
And let's combine this all together right now.
So I clear the screen and I applied once again.
All right.
And now let's get back our screen.
Let's trigger this function and see what happens.
I hit script in 3 to 1.
There we have it.
We are in the script string.
We are leaving the script string right now.
Perfect.
So we can see this one works out.
I mean, it doesn't look that complicated anymore, right?
Regarding to this one, I mean, yeah, we have to memorize some new stuff.
But regarding to the approach, it's pretty identical.
Unfortunately not.
And this is not even close being identical.
So we have seen this hilarious typecasting in our C++ code.
And if you now want to access these parameters, this will be messy.
Let's try to access them.
So, for example, you want to print out maybe let's do this underneath.
So over here.
Yes, I have to close it.
It's still laggy.
And there we go.
We do not want to send this.
So we want to print out the first parameter in first parameter.
And then this one should be ax zero.
And then you also want to print out the second parameter.
And this one here is the second parameter.
So these are our two parameters.
Let's put this a little bit more left and password and four.
So these should be printed out right now.
Right.
Let's see.
Let's copy this.
And let's get back to our free script.
Maybe let's keep this in foreground.
Let's also pull out our screen over here.
So here we have a screen.
And now let's see, I'm inserting this and I hit correct in three and two.
One.
All right.
It seems to work, but these are looking a little bit strange.
So this looks like addresses, right?
And yes, I guess these are addresses.
So it seems like I have forgot something.
Let's turn back to the slides and let's figure out what I did wrong over here.
Okay, so here we are back on the slides.
And yes, we've got four parameters.
So the first two are regarding to our chain I environment pointer.
The second one is this this object.
The third one is this parameter one, and the fourth one is parameter two.
All right, so absolutely my fault.
We have to hook Ark two and act three.
So counting from zero.
And this one here is Ark zero.
Ark one are two and three.
All right, let's simply fix this over here.
So back to this one.
And this one is two.
And this one over here is Ark three.
And let's do this once again.
Okay.
Sorry.
Let's get it over here.
So I had crept in and two.
One.
Let's go.
Who?
Something is interesting.
We still get first, second, first, second.
So besides forgetting about renaming this, we've got it now twice.
And this is something I encounter a lot.
So overriding a method regarding to intercept or attach is not a good idea.
We will overwrite it and on the second attempt we will overwrite the first overwrite and then we have
this mess over here.
Therefore, let's simply close this application and restart it.
I mean, we can also save this and provide it to file, but for now, let's do it in the command line.
I guess that's a little bit easier.
Okay.
So now we are restarting this application and I guess this one is not long.
I required this JDK therefore let me switch this real quick because my Java seems to lack a lot right
now.
Okay, so here we're getting back our screen.
Okay.
So let's try this over here.
So I hit crypt, then two, one.
There we go.
And the first parameter is, what is this?
The second parameter is four.
Finally, we have one value in there.
So this is our value for.
All right, this is amazing, but this one is ridiculous.
So what is this one over here?
Okay, so over here it seems like we are having an address.
Once again, this might be in string, but it might be in different type of string.
So we cannot simply print it out in this way.
We could try something like Let's see and trace.
Stringy.
Fine.
Let's see if this works.
Okay.
So I had said, we run this once again.
I am providing it and.
Here we have it.
Okay.
Let's see.
Yes.
Even tracing stringy fibers, not being able to get the the real string out of this address.
So the only approach right now I know is converting this into a real Java string.
And this can be done with Java DOT cast.
So if you're taking a look into the free documentation.
So this one over here within Docs, we've got the JavaScript up here and here we have something in podcast.
Matt we have it here and create a JavaScript wrapper.
Given the existing instance at handle of given class class as returned from Java use.
So first we need to use Java.
Don't use.
Over here.
Yes.
Perfect.
We can see this over here.
We are using the Java dot use for the string class and then we are type casting this one, this address
to this string and afterwards we are being able to to print this string.
All right.
Okay.
I guess now you know why this one is being called the hard way.
All right, let's do this.
So let's see what's the Java string class?
And therefore I'm searching for Android developer Java String.
And here we have the developer Android dot com the documentation and we can see the string is from the
class in Java length string.
All right, let's do this right now.
So this one over here, let's see this one.
This needs now to be type casted.
So we need to do it in the following way.
And first we need to get the class reference on string.
String class ref.
We can do this with Shabbat or use and let's put this on the right.
So he'd be having there we have it in Java lang string.
So now we're having this reference.
This needs to be within the on entry method.
And now we can create a new instance in the string instance and we can typecast it right now in the
following way.
I mean, we can have look into the documentation and it's exactly this one over here.
So we can use Java cast.
Then we provide this pointer which makes sure that this one which we are providing over here is in pointer.
So we are providing this ax three and we want to typecast it right now to our class reference and string
class reference.
All right.
Now we are having finally a string that can be printed out, hopefully.
Let's see.
Okay.
And therefore, let's go back into this one.
Close this one.
We insert it and now we're using screen copy.
Let's see if this one here works right now.
So I hit encrypt and 3 to 1.
Okay.
It did crash.
That's unfortunate.
Let's see.
There's a problem regarding to this point.
And here we can see the string chain I error detected use of invalid object and zero four.
Okay, let me let me check this out.
What did I do wrong?
Yes.
I am absolutely sorry for this one.
And this one is it's not our integer.
This is our string value.
So we have to change it from 3 to 2.
And let's see.
Yet this one is our first parameter.
So I'm not sure what I was thinking about right now.
Okay.
But it's good to see that those free to typecast handling works probably.
All right.
So this is our our string argument are two and first one is chain e environment pointer.
Then we are having the this object, then we're having our password, which is this one, and then we
have our our integer parameter.
All right, let's try this once again.
Sorry, not here.
Well.
Well, here.
The process has completely died, so we have to restart it.
We're using Frida to restart it.
Here we have it and yes, we are attached.
So now I'm pasting it in.
And now let's see if this works out.
So.
Three, two, one.
There we have it.
You take me app hacking.
And this is our string that we are providing to this function.
Yes.
So now we can see we are having a string and our integer value.
I mean, it's in hex, but this is fine for us right now.
We could also typecast this to an integer value, or we can also use functions like two inch 32, I
guess.
And let me let me check this out.
If it wasn't this way to end.
Yes, to end 32, maybe.
Let's do this real quick.
I guess this is how we can convert this into an integer value.
Okay.
So it started once again.
From then.
Let's see.
Yes.
All right.
So now we have it all.
So here, this is our integer value.
You can see this documentation over here.
That's a treasure.
There's a lot of stuff in here.
And yeah, I really highly recommend reading about this.
I mean, there's a lot of stuff and most of them is really complex.
I'm absolutely honest with you at this point.
But sometimes you can also have some some quick shots like this one, for example, type casting a native
pointer to an integer.
All right.
Now, I did note that this one is named to integer, but at least we could find this in the documentation.
Alrighty.
Okay.
So now we can also try printing out the return value over here in this one.
And let's see this time.
Let's do it this way.
Let's first print it out and see what it is.
And then we try to print it out.
Or maybe not.
Let's see.
Implication restarted.
We are entering this.
We are heading crept.
And we can see the return value is hex 71.
This is not even it doesn't look like a point there anymore.
Right.
And yeah, printing out the return value is an topic on itself, which we will cover in the next video.
For now, we stick to this one.
So we have seen how complex this is printing out those values regarding to in string most of the time,
I guess barely all the time.
We have to typecast it, but we can see how we can do this in the following way.
Printing out integer values.
Okay, this one works on a hex base.
But yeah, we can also use this function to integer 32 to print this out.
Okay.
For now, this is all for this video in case of any questions.
As always, feel free to write me a message and otherwise.
I'm looking forward to see you in the next video.
See you there.